diff --git a/Readme.md b/Readme.md index 1ba1879..0feb278 100644 --- a/Readme.md +++ b/Readme.md @@ -36,6 +36,21 @@ $aws_gc->getStatus(); // getAmount, getCurrency ``` +#### Throttle Rates + +Note that you can only send 10 requests per second. On a Throttle Excepion you need to wait about 10s to create another request. + +Recommended to pool requests. Or check when last requests where sent and then process them. + +#### On F400 errors + +1) try again +2) if failed run cancel gift card +3) if cance ok try create again with different request id +4) if 2) failed, wait a view seconds and try again +5) if 10s elapse, we need to wait a full day +6) if >24h call Amazon + ### cancel gift card ```php diff --git a/src/Amazon/AmazonIncentives.php b/src/Amazon/AmazonIncentives.php index 0dac5ea..d7c8217 100644 --- a/src/Amazon/AmazonIncentives.php +++ b/src/Amazon/AmazonIncentives.php @@ -81,21 +81,6 @@ class AmazonIncentives // PUBLIC METHODS // ********************************************************************* - // public function activateGiftCard(): array - // { - // return []; - // } - - // public function deactivateGiftCard(string $card_id): array - // { - // return []; - // } - - // public function activationStatusCheck(string $card_id): array - // { - // return []; - // } - /** * @param float $value * @param string $creation_request_id AWS creationRequestId @@ -161,8 +146,21 @@ class AmazonIncentives */ public static function decodeExceptionMessage(string $message): array { - return json_decode($message, true); + $message_ar = json_decode($message, true); + // if we have an error, build empty block and only fill message + if (json_last_error()) { + $message_ar = [ + 'status' => '', + 'code' => '', + 'type' => '', + 'message' => $message, + 'log_id' => '', + 'log' => [] + ]; + } + return $message_ar; } + // ********************************************************************* // PUBLIC TEST METHODS // ********************************************************************* diff --git a/src/Amazon/Client/Client.php b/src/Amazon/Client/Client.php index 45a1bcd..e44201f 100644 --- a/src/Amazon/Client/Client.php +++ b/src/Amazon/Client/Client.php @@ -40,10 +40,20 @@ class Client implements ClientInterface AmazonDebug::writeLog(['CURL_REQUEST_RESULT' => $result]); // extract all the error codes from Amazon $result_ar = json_decode($result, true); - $error_status = $result_ar['agcodResponse']['status'] ?? 'FAILURE'; - $error_code = $result_ar['errorCode'] ?? 'E999'; - $error_type = $result_ar['errorType'] ?? 'OtherUnknownError'; - $message = $result_ar['message'] ?? 'Unknown error occured'; + // if message is 'Rate exceeded', set different error + if (($result_ar['message'] ?? '') == 'Rate exceeded') { + $error_status = 'RESEND'; + $error_code = 'T001'; + $error_type = 'RateExceeded'; + $message = $result_ar['message']; + } else { + // for all other error messages + $error_status = $result_ar['agcodResponse']['status'] ?? 'FAILURE'; + $error_code = $result_ar['errorCode'] ?? 'E999'; + $error_type = $result_ar['errorType'] ?? 'OtherUnknownError'; + $message = $result_ar['message'] ?? 'Unknown error occured'; + } + // throw Error here with all codes throw AmazonErrors::getError( $error_status, $error_code, @@ -84,7 +94,14 @@ class Client implements ClientInterface $msg = 'Unexpected error communicating with AWS. ' . $message; } - throw new \RuntimeException($msg); + // throw an error like in the normal reqeust, but set to CURL error + throw AmazonErrors::getError( + 'FAILURE', + 'C001', + 'CurlError', + $message, + $errno + ); } } diff --git a/test/aws_gift_card_tests.php b/test/aws_gift_card_tests.php index 959fcff..49edea6 100644 --- a/test/aws_gift_card_tests.php +++ b/test/aws_gift_card_tests.php @@ -61,101 +61,167 @@ AED for UAE */ -// run tests -// print "checkMe Static:
" . print_r(Amazon\AmazonIncentives::checkMeStatic(), true) . "
"; +// run test to get funds info +$run_fund_test = false; +// run the normal get/cancel gift card tests +$run_gift_tests = true; +// run mock error check tests +$run_mocks = false; + +// should we print debug info +$debug_print = false; +// how long to wait between each call +$debug_wait = 2; +// if set to true will print all the debug logs too +$mock_debug = false; +// wait in seconds between mock tests +$mock_wait = 2; $aws = new Amazon\AmazonIncentives(); // $aws->createGiftCard(100); print "checkMe:
" . print_r($aws->checkMe(), true) . "
"; print "
"; + // we should open log file to collect all creationRequestId/gcId // so we can test and cancel // check balance -try { - $aws_test = Amazon\AmazonIncentives::make()->getAvailableFunds(); - print "AWS: getAvailableFunds:
" . print_r($aws_test, true) . "

"; -} catch (Exception $e) { - print "AWS: getAvailableFunds FAILURE [" . $e->getCode() . "]: " - . "
" . print_r(Amazon\AmazonIncentives::decodeExceptionMessage($e->getMessage()), true) . "

"; - exit; -}; -// print "LOG:
" . print_r($aws_test->getLog(), true) . "

"; -print "
"; - -// skip early for testing -// exit; - -/* -// create card -$value = 1000; -// we must be sure we pass FLOAT there -$aws_test = Amazon\AmazonIncentives::make()->buyGiftCard((float)$value); -$creation_request_id = $aws_test->getCreationRequestId(); -$gift_card_id = $aws_test->getId(); -$claim_code = $aws_test->getClaimCode(); -print "AWS: buyGiftCard: " - . "creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id . ", " - . "CLAIM CODE: " . $claim_code . "
"; -// print "
" . print_r($aws_test, true) . "

"; -print "
"; -// cancel card -$aws_test = Amazon\AmazonIncentives::make()->cancelGiftCard($creation_request_id, $gift_card_id); -print "AWS: buyGiftCard:
" . print_r($aws_test, true) . "

"; -print "
"; - */ - -// MOCK TEST - -$mock_ok = 'MOCK OK'; -$mock_failure = 'MOCK FAILURE'; - -$mock['F0000'] = [ 'ret' => '', 'st' => 'SUCCESS']; -$mock['F2005'] = [ 'ret' => 'F200', 'st' => 'FAILURE']; -$mock['F2010'] = [ 'ret' => 'F200', 'st' => 'FAILURE']; -$mock['F4000'] = [ 'ret' => 'F400', 'st' => 'RESEND']; -$value = 500; -foreach ($mock as $creation_id => $mock_return) { +if ($run_fund_test === true) { try { - $aws_test = Amazon\AmazonIncentives::make()->buyGiftCard((float)$value, $creation_id); - $creation_request_id = $aws_test->getCreationRequestId(); - $gift_card_id = $aws_test->getId(); - $claim_code = $aws_test->getClaimCode(); - $request_status = $aws_test->getStatus(); - print "AWS: MOCK: " . $creation_id . ": buyGiftCard: " . $request_status . ": " - . "creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id . ", " - . "CLAIM CODE: " . $claim_code . ": "; - if ($mock_return['st'] == $request_status) { - print $mock_ok; - } else { - print $mock_failure; - } - // print "
" . print_r($aws_test, true) . "
"; - print "
"; + $aws_test = Amazon\AmazonIncentives::make()->getAvailableFunds(); + print "AWS: getAvailableFunds:
" . print_r($aws_test, true) . "

"; } catch (Exception $e) { - $error = Amazon\AmazonIncentives::decodeExceptionMessage($e->getMessage()); - print "AWS: MOCK: " . $creation_id . ": buyGiftCard: " . $error['status'] + print "AWS: getAvailableFunds: " . $error['status'] . " [" . $e->getCode() . "]: " . $error['code'] . " | " . $error['type'] . " | " . $error['message'] . ": "; - if ( - $mock_return['ret'] == $error['code'] && - $mock_return['st'] == $error['status'] - ) { - print $mock_ok; - } else { - print $mock_failure; + if ($debug_print === true) { + print "/
" . print_r($error['log'][$error['log_id'] ?? ''] ?? [], true) . "
"; } - // print "
" . print_r($error['log'][$error['log_id'] ?? ''] ?? [], true) . "
"; - print "
"; - } + }; + sleep($debug_wait); + // print "LOG:
" . print_r($aws_test->getLog(), true) . "

"; + print "
"; } -print "
"; -// ... should do all possible important mock tests +if ($run_gift_tests === true) { + // create card + $value = 1000; + // we must be sure we pass FLOAT there + $aws_test = Amazon\AmazonIncentives::make()->buyGiftCard((float)$value); + $creation_request_id = $aws_test->getCreationRequestId(); + $gift_card_id = $aws_test->getId(); + $claim_code = $aws_test->getClaimCode(); + $request_status = $aws_test->getStatus(); + print "AWS: buyGiftCard: " . $request_status . ": " + . "creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id . ", " + . "CLAIM CODE: " . $claim_code . "
"; + if ($debug_print === true) { + print "
" . print_r($aws_test, true) . "

"; + } + sleep($debug_wait); + print "
"; + // cancel above created card card + $aws_test = Amazon\AmazonIncentives::make()->cancelGiftCard($creation_request_id, $gift_card_id); + $request_status = $aws_test->getStatus(); + print "AWS: cancelGiftCard: " . $request_status . ": " + . "creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id + . "
"; + if ($debug_print === true) { + print "
" . print_r($aws_test, true) . "

"; + } + print "
"; + sleep($debug_wait); -// failed card (invalid data) -// double card + // set same request ID twice to get same response test + $aws_test = Amazon\AmazonIncentives::make()->buyGiftCard((float)$value); + $creation_request_id = $aws_test->getCreationRequestId(); + $gift_card_id = $aws_test->getId(); + $claim_code = $aws_test->getClaimCode(); + $request_status = $aws_test->getStatus(); + print "AWS: buyGiftCard: CODE A: " . $request_status . ": " + . "creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id . ", " + . "CLAIM CODE: " . $claim_code . "
"; + if ($debug_print === true) { + print "
" . print_r($aws_test, true) . "

"; + } + sleep($debug_wait); + $aws_test = Amazon\AmazonIncentives::make()->buyGiftCard((float)$value, $creation_request_id); + $request_status = $aws_test->getStatus(); + print "AWS: buyGiftCard: SAME CODE A AGAIN: " . $request_status . ": " + . "creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id . ", " + . "CLAIM CODE: " . $claim_code . "
"; + if ($debug_print === true) { + print "
" . print_r($aws_test, true) . "

"; + } + print "
"; + sleep($debug_wait); +} + +// MOCK TEST +if ($mock_debug === true) { + $mock_ok = 'MOCK OK'; + $mock_failure = 'MOCK FAILURE'; + $mock_value = 500; + + $mock['F0000'] = [ 'ret' => '', 'st' => 'SUCCESS']; // success mock + $mock['F2003'] = [ 'ret' => 'F200', 'st' => 'FAILURE']; // InvalidAmountInput + $mock['F2004'] = [ 'ret' => 'F200', 'st' => 'FAILURE']; // InvalidAmountValue + $mock['F2005'] = [ 'ret' => 'F200', 'st' => 'FAILURE']; // InvalidCurrencyCodeInput + $mock['F2010'] = [ 'ret' => 'F200', 'st' => 'FAILURE']; // CardActivatedWithDifferentRequestId + $mock['F2015'] = [ 'ret' => 'F200', 'st' => 'FAILURE']; // MaxAmountExceeded + $mock['F2016'] = [ 'ret' => 'F200', 'st' => 'FAILURE']; // CurrencyCodeMismatch + $mock['F2017'] = [ 'ret' => 'F200', 'st' => 'FAILURE']; // FractionalAmountNotAllowed + $mock['F2047'] = [ 'ret' => 'F200', 'st' => 'FAILURE']; // CancelRequestArrivedAfterTimeLimit + $mock['F3003'] = [ 'ret' => 'F300', 'st' => 'FAILURE']; // InsufficientFunds + $mock['F3005'] = [ 'ret' => 'F300', 'st' => 'FAILURE']; // AccountHasProblems + $mock['F3010'] = [ 'ret' => 'F300', 'st' => 'FAILURE']; // CustomerSurpassedDailyVelocityLimit + $mock['F4000'] = [ 'ret' => 'F400', 'st' => 'RESEND']; // SystemTemporarilyUnavailable + $mock['F5000'] = [ 'ret' => 'F500', 'st' => 'FAILURE']; // UnknownError + + foreach ($mock as $creation_id => $mock_return) { + try { + $aws_test = Amazon\AmazonIncentives::make()->buyGiftCard((float)$mock_value, $creation_id); + $creation_request_id = $aws_test->getCreationRequestId(); + $gift_card_id = $aws_test->getId(); + $claim_code = $aws_test->getClaimCode(); + $request_status = $aws_test->getStatus(); + print "AWS: MOCK: " . $creation_id . ": buyGiftCard: " . $request_status . ": " + . "creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id . ", " + . "CLAIM CODE: " . $claim_code . ": "; + if ($mock_return['st'] == $request_status) { + print $mock_ok; + } else { + print $mock_failure; + } + if ($mock_debug === true) { + print "
" . print_r($aws_test, true) . "
"; + } + print "
"; + } catch (Exception $e) { + $error = Amazon\AmazonIncentives::decodeExceptionMessage($e->getMessage()); + print "AWS: MOCK: " . $creation_id . ": buyGiftCard: " . $error['status'] + . " [" . $e->getCode() . "]: " + . $error['code'] . " | " . $error['type'] + . " | " . $error['message'] . ": "; + if ( + $mock_return['ret'] == $error['code'] && + $mock_return['st'] == $error['status'] + ) { + print $mock_ok; + } else { + print $mock_failure; + } + if ($mock_debug === true) { + print "/
" . print_r($error['log'][$error['log_id'] ?? ''] ?? [], true) . "
"; + } + print "
"; + } + // Waiting a moment, so we don't flood + sleep($mock_wait); + } + print "
"; +} // __END__