Add README file, add status to exception return

Because status RESEND/FAILURE has to be checked we also add this to the
Exception return json string.
Also handle unset errors (eg when we get an Rate Limit error)

Move the _ENV check into mtheod

test now has some basic mock tests
This commit is contained in:
2021-10-19 09:39:14 +09:00
parent b00d545a10
commit 71abd4d06e
6 changed files with 193 additions and 37 deletions

90
Readme.md Normal file
View File

@@ -0,0 +1,90 @@
# Amazon Incentives - Gift on Demand standa alone class
This is a abastract from (https://github.com/kamerk22/AmazonGiftCode) to be not dependend on Laravel base code.
Uses .env file to load configuration data
## _ENV variables needed
* AWS_GIFT_CARD_KEY
* AWS_GIFT_CARD_SECRET
* AWS_GIFT_CARD_PARTNER_ID
* AWS_GIFT_CARD_ENDPOINT
* AWS_GIFT_CARD_CURRENCY
* AWS_DEBUG (1/0)
## How to use
The class must be loaded with an autoloader (see test/autoloader.php for example).
The above _ENV variables must be set (Except AWS_DEBUG, defaults to off).
### create gift card
```php
$aws_gc = Amazon\AmazonIncentives::make()->buyGiftCard((float)$value);
// the two below are need if we want to cancel the card
// get gift card id (gcID)
$aws_gc->getId();
// get creation request id (creationRequestId)
$aws_gc->getCreationRequestId();
// the one below must be printed to the user
$aws_gc->getClaimCode();
// check status (SUCCESS/RESEND/FAILURE)
$aws_gc->getStatus();
// others:
// getAmount, getCurrency
```
### cancel gift card
```php
// use getCreationRequestId() and getId() from request
$aws_gc = Amazon\AmazonIncentives::make()->cancelGiftCard($creation_request_id, $gift_card_id);
// return is as above
```
### check balance
```php
$aws_gc = Amazon\AmazonIncentives::make()->getAvailableFunds();
```
## Exceptions
If the HTTPS request does not return 220 OK it will throw an exception.
The error code is the curl handler error code.
The error message is json encoded array with the layout
```php
[
'status' => 'AWS Status FAILURE or RESEND',
'code' => 'AWS Error Code Fnnn',
'type' => 'AWS Error info',
'message' => 'AWS long error message',
'log_id' => 'If logging is on the current log id',
'log' => 'The complete log collected over all calls',
]
```
`status`, `code` and `type` must be checked on a failure.
**NOTE**: if code is E999 then this is a request flood error:
In this case the request has to be resend after a certain waiting period.
## Debugging
If AWS_DEBUG is set to 1 and internal array will be written with debug info.
The Amazon\Debug\AmazonDebug class handles all this.
In the Amazon\AWS\AWS main class the debugger gets set
* setFlag that turns debugger on/off
* setId (to set unique id for each run)
New entries can be written with
`AmazonDebug::writeLog(['foo' => 'bar']);`
On sucessful run the log data is accessable with `$aws->getLog()`
On exception the log data is in the error message json (see exceptions)

View File

@@ -3,6 +3,7 @@
namespace Amazon\Client;
use Amazon\Exceptions\AmazonErrors;
use Amazon\Debug\AmazonDebug;
class Client implements ClientInterface
{
@@ -36,11 +37,15 @@ class Client implements ClientInterface
if (curl_getinfo($handle, CURLINFO_HTTP_CODE) !== self::HTTP_OK) {
$err = curl_errno($handle);
AmazonDebug::writeLog(['CURL_REQUEST_RESULT' => $result]);
// extract all the error codes from Amazon
$error_code = json_decode($result)->errorCode;
$error_type = json_decode($result)->errorType;
$message = json_decode($result)->message;
$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';
throw AmazonErrors::getError(
$error_status,
$error_code,
$error_type,
$message,

View File

@@ -44,12 +44,39 @@ class Config implements ConfigInterface
?string $currency,
?bool $debug,
) {
$this->setAccessKey($key ?: $_ENV['AWS_GIFT_CARD_KEY'] ?? '');
$this->setSecret($secret ?: $_ENV['AWS_GIFT_CARD_SECRET'] ?? '');
$this->setPartner($partner ?: $_ENV['AWS_GIFT_CARD_PARTNER_ID'] ?? '');
$this->setEndpoint($endpoint ?: $_ENV['AWS_GIFT_CARD_ENDPOINT'] ?? '');
$this->setCurrency($currency ?: $_ENV['AWS_GIFT_CARD_CURRENCY'] ?? '');
$this->setDebug($debug ?: (!empty($_ENV['AWS_DEBUG']) ? true : false));
$this->setAccessKey($key ?: $this->parseEnv('AWS_GIFT_CARD_KEY'));
$this->setSecret($secret ?: $this->parseEnv('AWS_GIFT_CARD_SECRET'));
$this->setPartner($partner ?: $this->parseEnv('AWS_GIFT_CARD_PARTNER_ID'));
$this->setEndpoint($endpoint ?: $this->parseEnv('AWS_GIFT_CARD_ENDPOINT'));
$this->setCurrency($currency ?: $this->parseEnv('AWS_GIFT_CARD_CURRENCY'));
$this->setDebug($debug ?: $this->parseEnv('AWS_DEBUG'));
}
/**
* string key to search, returns entry from _ENV
* if not matchin key, returns empty
*
* @param string $key To search in _ENV array
* @return string|bool Returns either string or true/false (DEBUG flag)
*/
private function parseEnv(string $key)
{
$return = '';
switch ($key) {
case 'AWS_DEBUG':
$return = !empty($_ENV['AWS_DEBUG']) ? true : false;
break;
case 'AWS_GIFT_CARD_KEY':
case 'AWS_GIFT_CARD_SECRET':
case 'AWS_GIFT_CARD_PARTNER_ID':
case 'AWS_GIFT_CARD_ENDPOINT':
case 'AWS_GIFT_CARD_CURRENCY':
$return = $_ENV[$key] ?? '';
break;
default:
break;
}
return $return;
}
/**

View File

@@ -58,6 +58,17 @@ interface ConfigInterface
* @return $this
*/
public function setPartner(string $partner): ConfigInterface;
/**
* @return bool
*/
public function getDebug(): bool;
/**
* @param bool $debug
* @return $this
*/
public function setDebug(bool $debug): ConfigInterface;
}
// __END__

View File

@@ -7,6 +7,7 @@ use RuntimeException;
class AmazonErrors extends RuntimeException
{
/**
* @param string $error_status agcodResponse->status from Amazon
* @param string $error_code errorCode from Amazon
* @param string $error_type errorType from Amazon
* @param string $message
@@ -14,6 +15,7 @@ class AmazonErrors extends RuntimeException
* @return AmazonErrors
*/
public static function getError(
string $error_status,
string $error_code,
string $error_type,
string $message,
@@ -22,6 +24,7 @@ class AmazonErrors extends RuntimeException
// NOTE: if xdebug.show_exception_trace is set to 1 this will print ERRORS
return new static(
json_encode([
'status' => $error_status,
'code' => $error_code,
'type' => $error_type,
'message' => $message,

View File

@@ -92,14 +92,14 @@ print "<hr>";
$value = 1000;
// we must be sure we pass FLOAT there
$aws_test = Amazon\AmazonIncentives::make()->buyGiftCard((float)$value);
print "AWS: buyGiftCard: <pre>" . print_r($aws_test, true) . "</pre><br>";
$creation_request_id = $aws_test->getCreationRequestId();
$gift_card_id = $aws_test->getId();
$claim_code = $aws_test->getClaimCode();
print "AWS creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id . "<br>";
print "AWS CLAIM CODE: <b>" . $claim_code . "</b><br>";
print "AWS: buyGiftCard: "
. "creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id . ", "
. "CLAIM CODE: <b>" . $claim_code . "</b><br>";
// print "<pre>" . print_r($aws_test, true) . "</pre><br>";
print "<hr>";
// cancel card
$aws_test = Amazon\AmazonIncentives::make()->cancelGiftCard($creation_request_id, $gift_card_id);
print "AWS: buyGiftCard: <pre>" . print_r($aws_test, true) . "</pre><br>";
@@ -107,29 +107,49 @@ print "<hr>";
*/
// MOCK TEST
$value = 500;
$creation_id = 'F0000';
$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();
print "AWS: MOCK: " . $creation_id . ": buyGiftCard: <pre>" . print_r($aws_test, true) . "</pre><br>";
print "AWS creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id . "<br>";
print "AWS CLAIM CODE: <b>" . $claim_code . "</b><br>";
print "<hr>";
$creation_id = 'F2005';
$mock_ok = '<span style="color:green;">MOCK OK</span>';
$mock_failure = '<span style="color:red;">MOCK FAILURE</span>';
$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) {
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();
print "AWS: MOCK: " . $creation_id . ": buyGiftCard: <pre>" . print_r($aws_test, true) . "</pre><br>";
print "AWS creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id . "<br>";
print "AWS CLAIM CODE: <b>" . $claim_code . "</b><br>";
$request_status = $aws_test->getStatus();
print "AWS: MOCK: " . $creation_id . ": buyGiftCard: " . $request_status . ": "
. "creationRequestId: " . $creation_request_id . ", gcId: " . $gift_card_id . ", "
. "CLAIM CODE: <b>" . $claim_code . "</b>: ";
if ($mock_return['st'] == $request_status) {
print $mock_ok;
} else {
print $mock_failure;
}
// print "<pre>" . print_r($aws_test, true) . "</pre>";
print "<br>";
} catch (Exception $e) {
print "AWS: MOCK: " . $creation_id . ": buyGiftCard: FAILURE [" . $e->getCode() . "]: "
. "<pre>" . print_r(Amazon\AmazonIncentives::decodeExceptionMessage($e->getMessage()), true) . "</pre><br>";
$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;
}
// print "<pre>" . print_r($error['log'][$error['log_id'] ?? ''] ?? [], true) . "</pre>";
print "<br>";
}
}
print "<hr>";