Refund payments using Authorize.net AIM API - php

I am trying to find a way to refund payments using Authorize.net's AIM API. I found sample code located here: https://github.com/stymiee/Authorize.Net-XML. Here is the code that I am using from the sample:
require('../../config.inc.php');
require('../../AuthnetXML.class.php');
$xml = new AuthnetXML(AUTHNET_LOGIN, AUTHNET_TRANSKEY, AuthnetXML::USE_DEVELOPMENT_SERVER);
$xml->createTransactionRequest(array(
'refId' => rand(1000000, 100000000),
'transactionRequest' => array(
'transactionType' => 'refundTransaction',
'amount' => 5,
'payment' => array(
'creditCard' => array(
'cardNumber' => 'XXXX1111',
'expirationDate' => '122016'
)
),
'authCode' => '2165668159'
),
));
I keep getting an error message saying that the card code is missing. Any thoughts on what is missing to allow a refund to go through?
NEW CODE:
$xml = new AuthnetXML(AUTHNET_LOGIN, AUTHNET_TRANSKEY);
$xml->createTransactionRequest(array(
'refId' => rand(1000000, 100000000),
'transactionRequest' => array(
'transactionType' => 'refundTransaction',
'amount' => 1.00,
'payment' => array(
'creditCard' => array(
'cardNumber' => 'XXXX1014',
'expirationDate' => '122025',
)
),
'refTransId' => '4928163616',
),
));

$xml = new AuthnetXML(AUTHNET_LOGIN, AUTHNET_TRANSKEY);
$xml->createTransactionRequest(array(
'refId' => rand(1000000, 100000000),
'transactionRequest' => array(
'transactionType' => 'refundTransaction',
'amount' => 1.00,
'payment' => array(
'creditCard' => array(
'cardNumber' => 'XXXX1014',
'expirationDate' => '122025',
)
),
'refTransId' => '4928163616',
'transactionSettings' => array(
'setting' => array(
0 => array(
'settingName' => 'emailCustomer',
'settingValue' => 'true'
),
)
),
),
));

Related

Brazilian shipping adress normalization status

I'm facing an issue with the integration of the paypal PHP Api on my website.
When i try to buy something with a brazilian sandbox account when going to my paypal_payment_succes.php page i get the following error when executing the payment:
{"name":"VALIDATION_ERROR","details":[{"field":"transactions[0].item_list.shipping_address.normalization_status","issue":"Field name is not defined for this resource type."}],"message":"Invalid request. See details.","information_link":"https://developer.paypal.com/docs/api/payments/#errors","debug_id":"e0f0cecbd95f3"}
It seems to be an issue with the adress normalization but i'm not able to solve it on my own.
Here is the creation of the request:
$payer = new \PayPal\Api\Payer();
$payer->setPaymentMethod('paypal');
$list = new \PayPal\Api\ItemList();
$item = new \PayPal\Api\Item();
$item->setName("myItem");
$item->setPrice($iten_ht_price);
$item->setCurrency('EUR');
$item->setQuantity(1);
$list->addItem($item);
$details = new \PayPal\Api\Details();
$details->setSubtotal($iten_ht_price);
$details->setTax($item_taxes);
$amount = new \PayPal\Api\Amount();
$amount->setTotal($item_ttc_price);
$amount->setCurrency('EUR');
$amount->setDetails($details);
$transaction = new \PayPal\Api\Transaction();
$transaction->setItemList($list);
$transaction->setDescription($service_info["NAME"]);
$transaction->setAmount($amount);
$redirectUrls = new \PayPal\Api\RedirectUrls();
$redirectUrls->setReturnUrl("https://example.com/paypal_payment_success.php")
->setCancelUrl("https://example.com/paypal_payment_cancel.php");
$payment = new \PayPal\Api\Payment();
$payment->setIntent('sale')
->setPayer($payer)
->setTransactions(array($transaction))
->setRedirectUrls($redirectUrls);
try {
$payment->create($apiContext);
?>
<script type="text/javascript">
window.location.href = '<?php echo $payment->getApprovalLink(); ?>';
</script>
<?php
}
and here is the payment validation:
$payment = \PayPal\Api\Payment::get($_GET['paymentId'], $apiContext);
$execution = new \PayPal\Api\PaymentExecution();
$execution->setPayerId($_GET["PayerID"])
->setTransactions($payment->getTransactions());
try {
$payment->execute($execution, $apiContext);
}
catch (\PayPal\Exception\PayPalConnectionException $ex) {
echo '<div class="alert alert-danger"><strong>'.$l["error_happend"].'</strong></div>';
echo $ex->getData();
error_log("paypal_payment_success.php error: ". $ex->getData());
}
here is the full content of the $payment variable:
PayPal\Api\Payment::__set_state(array(
'_propMap' =>
array (
'id' => 'PAYID-LR6OIAQ8K6195799T910831S',
'intent' => 'sale',
'state' => 'created',
'cart' => '8GR605689F1809928',
'payer' =>
PayPal\Api\Payer::__set_state(array(
'_propMap' =>
array (
'payment_method' => 'paypal',
'status' => 'VERIFIED',
'payer_info' =>
PayPal\Api\PayerInfo::__set_state(array(
'_propMap' =>
array (
'email' => 'billing-brazil1#example.com',
'first_name' => 'Mg',
'last_name' => 'Doctor',
'payer_id' => 'LQX9UCM6YMM96',
'shipping_address' =>
PayPal\Api\ShippingAddress::__set_state(array(
'_propMap' =>
array (
'recipient_name' => 'Mg Doctor',
'line1' => '1234 Rua Main',
'city' => 'Rio De Janeiro',
'state' => 'RJ',
'postal_code' => '22021-001',
'country_code' => 'BR',
'normalization_status' => 'UNNORMALIZED_USER_PREFERRED',
),
)),
'tax_id_type' => 'BR_CPF',
'tax_id' => '30949017787',
'country_code' => 'BR',
),
)),
),
)),
'transactions' =>
array (
0 =>
PayPal\Api\Transaction::__set_state(array(
'_propMap' =>
array (
'amount' =>
PayPal\Api\Amount::__set_state(array(
'_propMap' =>
array (
'total' => '2.50',
'currency' => 'EUR',
'details' =>
PayPal\Api\Details::__set_state(array(
'_propMap' =>
array (
'subtotal' => '2.00',
'tax' => '0.50',
),
)),
),
)),
'payee' =>
PayPal\Api\Payee::__set_state(array(
'_propMap' =>
array (
'merchant_id' => 'WTK64MCV7B6NC',
'email' => 'billing-facilitator#example.com',
),
)),
'description' => 'SeedBox Starter',
'custom' => '57|6|1|2.50|NEW',
'item_list' =>
PayPal\Api\ItemList::__set_state(array(
'_propMap' =>
array (
'items' =>
array (
0 =>
PayPal\Api\Item::__set_state(array(
'_propMap' =>
array (
'name' => 'SeedBox Starter | Achat | 1 mois',
'price' => '2.00',
'currency' => 'EUR',
'quantity' => 1,
),
)),
),
'shipping_address' =>
PayPal\Api\ShippingAddress::__set_state(array(
'_propMap' =>
array (
'recipient_name' => 'Mg Doctor',
'line1' => '1234 Rua Main',
'city' => 'Rio De Janeiro',
'state' => 'RJ',
'postal_code' => '22021-001',
'country_code' => 'BR',
'normalization_status' => 'UNNORMALIZED_USER_PREFERRED',
),
)),
),
)),
'related_resources' =>
array (
),
),
)),
),
'redirect_urls' =>
PayPal\Api\RedirectUrls::__set_state(array(
'_propMap' =>
array (
'return_url' => 'https://example.com/paypal_payment_success.php?paymentId=PAYID-LR6OIAQ8K6195799T910831S',
'cancel_url' => 'https://example.com/paypal_payment_cancel.php',
),
)),
'create_time' => '2019-03-04T08:38:26Z',
'update_time' => '2019-03-04T08:38:45Z',
'links' =>
array (
0 =>
PayPal\Api\Links::__set_state(array(
'_propMap' =>
array (
'href' => 'https://api.sandbox.paypal.com/v1/payments/payment/PAYID-LR6OIAQ8K6195799T910831S',
'rel' => 'self',
'method' => 'GET',
),
)),
1 =>
PayPal\Api\Links::__set_state(array(
'_propMap' =>
array (
'href' => 'https://api.sandbox.paypal.com/v1/payments/payment/PAYID-LR6OIAQ8K6195799T910831S/execute',
'rel' => 'execute',
'method' => 'POST',
),
)),
2 =>
PayPal\Api\Links::__set_state(array(
'_propMap' =>
array (
'href' => 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-8GR605689F1809928',
'rel' => 'approval_url',
'method' => 'REDIRECT',
),
)),
),
),
))
In advance thank you :)

Typo3 use realurl to mask tx_news_pi1 parameter in URL

I am pretty new to typo3. The Website is all set up now i want to use realurl to make some human readable URLS.
Out of the boy it works pretty well. But not for my news sites.
http://myDomain/news-events/news/Name-of-the-Article/?tx_news_pi1%5Bday%5D=19&tx_news_pi1%5Bmonth%5D=7&tx_news_pi1%5Byear%5D=2017&cHash=6af067caeb037b4de744f6b9e07b73e8
Please help me to get rid of the last Parameters.
to get something like:
http://myDomain/news-events/news/Name-of-the-Article/
Here is my realurl_conf
[ See Update]
Thank you all for your time =)
Update:
So i worked my way through the manual.
I copied from them and inserted my IDs and Stuff
this is my new Configuration [ Deleted the first one ]
<?php
$GLOBALS['TYPO3_CONF_VARS']['FE']['addRootLineFields'] .= ',tx_realurl_pathsegment';
// Adjust to your needs
$domain = 'http://mydomain.de';
$rootPageUid = 1;
#$rssFeedPageType = 9818; // pageType of your RSS feed page
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl'][$domain] = array(
'pagePath' => array(
'type' => 'user',
'userFunc' => 'EXT:realurl/class.tx_realurl_advanced.php:&tx_realurl_advanced->main',
'spaceCharacter' => '-',
'languageGetVar' => 'L',
'expireDays' => '3',
'rootpage_id' => $rootPageUid,
'firstHitPathCache' => 1
),
'init' => array(
'enableCHashCache' => TRUE,
'respectSimulateStaticURLs' => 0,
'appendMissingSlash' => 'ifNotFile,redirect',
'adminJumpToBackend' => TRUE,
'enableUrlDecodeCache' => TRUE,
'enableUrlEncodeCache' => TRUE,
'emptyUrlReturnValue' => '/',
),
'fileName' => array(
'defaultToHTMLsuffixOnPrev' => 0,
'acceptHTMLsuffix' => 1,
'index' => array(
# 'feed.rss' => array(
# 'keyValues' => array(
# 'type' => $rssFeedPageType,
# )
# )
)
),
'preVars' => array(
array(
'GETvar' => 'L',
'valueMap' => array(
# 'en' => '1',
),
'noMatch' => 'bypass',
),
array(
'GETvar' => 'no_cache',
'valueMap' => array(
'nc' => 1,
),
'noMatch' => 'bypass',
),
),
'fixedPostVars' => array(
'newsDetailConfiguration' => array(
array(
'GETvar' => 'tx_news_pi1[action]',
'valueMap' => array(
'detail' => '',
),
'noMatch' => 'bypass'
),
array(
'GETvar' => 'tx_news_pi1[controller]',
'valueMap' => array(
'News' => '',
),
'noMatch' => 'bypass'
),
array(
'GETvar' => 'tx_news_pi1[news]',
'lookUpTable' => array(
'table' => 'tx_news_domain_model_news',
'id_field' => 'uid',
'alias_field' => "CONCAT(uid, '-', IF(path_segment!='',path_segment,title))",
/** OR ***************/
'alias_field' => 'IF(path_segment!="",path_segment,title)',
/** OR ***************/
'alias_field' => "CONCAT(uid, '-', title)",
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => 1, # 1?
'useUniqueCache_conf' => array(
'strtolower' => 1,
'spaceCharacter' => '-'
),
'languageGetVar' => 'L',
'languageExceptionUids' => '',
'languageField' => 'sys_language_uid',
'transOrigPointerField' => 'l10n_parent',
'expireDays' => 180,
),
#Depends ?
array(
'GETvar' => 'tx_news_pi1[day]',
'noMatch' => 'bypass',
),
array(
'GETvar' => 'tx_news_pi1[month]',
'noMatch' => 'bypass',
),
array(
'GETvar' => 'tx_news_pi1[year]',
'noMatch' => 'bypass',
),
),
'newsCategoryConfiguration' => array(
array(
'GETvar' => 'tx_news_pi1[overwriteDemand][categories]',
'lookUpTable' => array(
'table' => 'sys_category',
'id_field' => 'uid',
'alias_field' => 'title',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => 1,
'useUniqueCache_conf' => array(
'strtolower' => 1,
'spaceCharacter' => '-'
)
)
)
),
'newsTagConfiguration' => array(
array(
'GETvar' => 'tx_news_pi1[overwriteDemand][tags]',
'lookUpTable' => array(
'table' => 'tx_news_domain_model_tag',
'id_field' => 'uid',
'alias_field' => 'title',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => 1,
'useUniqueCache_conf' => array(
'strtolower' => 1,
'spaceCharacter' => '-'
)
)
)
),
#TODO: ID-News Seite Finden
#'145' => 'newsDetailConfiguration',
#'147' => 'newsDetailConfiguration', // For additional detail pages, add their uid as well
#'134' => 'newsDetailConfiguration', // For additional detail pages, add their uid as well
'148' => 'newsDetailConfiguration', // For additional detail pages, add their uid as well
'149' => 'newsDetailConfiguration', // For additional detail pages, add their uid as well
#'71' => 'newsTagConfiguration',
#'72' => 'newsCategoryConfiguration',
),
'postVarSets' => array(
'_DEFAULT' => array(
'controller' => array(
array(
'GETvar' => 'tx_news_pi1[action]',
'noMatch' => 'bypass'
),
array(
'GETvar' => 'tx_news_pi1[controller]',
'noMatch' => 'bypass'
)
),
'dateFilter' => array(
array(
'GETvar' => 'tx_news_pi1[overwriteDemand][year]',
),
array(
'GETvar' => 'tx_news_pi1[overwriteDemand][month]',
),
),
'page' => array(
array(
'GETvar' => 'tx_news_pi1[#widget_0][currentPage]',
),
),
),
),
)
);
But still there are the
tx_news_pi1[day], tx_news_pi1[month], tx_news_pi1[year] and cHash
Parameters in the URL.
Please Help me to get rid of them.
thats my configuration:
<?php
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']=array (
'_DEFAULT' => array (
'init' => array (
'appendMissingSlash' => 'ifNotFile,redirect',
'emptyUrlReturnValue' => '/',
),
'pagePath' => array (
'rootpage_id' => '2',
),
'fileName' => array (
'defaultToHTMLsuffixOnPrev' => 0,
'acceptHTMLsuffix' => 1,
'index' => array (
'print' => array (
'keyValues' => array (
'type' => 98,
),
),
),
),
'preVars' => array(
array(
'GETvar' => 'L',
'valueMap' => array(
'en' => '1',
),
'noMatch' => 'bypass',
),
array(
'GETvar' => 'no_cache',
'valueMap' => array(
'nc' => 1,
),
'noMatch' => 'bypass',
),
),
'fixedPostVars' => array(
// config for single/detail news:
'newsDetailConfiguration' => array(
array(
'GETvar' => 'tx_news_pi1[action]',
'valueMap' => array(
'detail' => '',
),
'noMatch' => 'bypass'
),
array(
'GETvar' => 'tx_news_pi1[controller]',
'valueMap' => array(
'News' => '',
),
'noMatch' => 'bypass'
),
array(
'GETvar' => 'tx_news_pi1[news]',
'lookUpTable' => array(
'table' => 'tx_news_domain_model_news',
'id_field' => 'uid',
'alias_field' => 'concat(uid,\'_\',title)',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => 1,
'useUniqueCache_conf' => array(
'strtolower' => 1,
'spaceCharacter' => '-'
),
'languageGetVar' => 'L',
'languageExceptionUids' => '',
'languageField' => 'sys_language_uid',
'transOrigPointerField' => 'l10n_parent',
'autoUpdate' => 1,
'expireDays' => 180,
)
)
),
// config for category selection:
'newsCategoryConfiguration' => array(
array(
'GETvar' => 'tx_news_pi1[overwriteDemand][categories]',
'lookUpTable' => array(
'table' => 'sys_category',
'id_field' => 'uid',
'alias_field' => 'title',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => 1,
'useUniqueCache_conf' => array(
'strtolower' => 1,
'spaceCharacter' => '-'
)
)
)
),
// configuration for tag selection:
'newsTagConfiguration' => array(
array(
'GETvar' => 'tx_news_pi1[overwriteDemand][tags]',
'lookUpTable' => array(
'table' => 'tx_news_domain_model_tag',
'id_field' => 'uid',
'alias_field' => 'title',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => 1,
'useUniqueCache_conf' => array(
'strtolower' => 1,
'spaceCharacter' => '-'
)
)
)
),
// add your page uids where you have detail view of news:
'70' => 'newsDetailConfiguration',
//'701' => 'newsDetailConfiguration', // For additional detail pages, add their uid as well
/connect page uid for further views: tag-selection, category-selection"
'71' => 'newsTagConfiguration',
'72' => 'newsCategoryConfiguration',
),
'postVarSets' => array(
'_DEFAULT' => array(
'controller' => array(
array(
'GETvar' => 'tx_news_pi1[action]',
'noMatch' => 'bypass'
),
array(
'GETvar' => 'tx_news_pi1[controller]',
'noMatch' => 'bypass'
)
),
'dateFilter' => array(
array(
'GETvar' => 'tx_news_pi1[overwriteDemand][year]',
),
array(
'GETvar' => 'tx_news_pi1[overwriteDemand][month]',
),
),
'page' => array(
array(
'GETvar' => 'tx_news_pi1[#widget_0][currentPage]',
),
),
),
),
),
);
look for the right insertion in the array. For that have a clean indention!
The already mentioned link is quite useful and contains detailed info:
https://docs.typo3.org/typo3cms/extensions/news/AdministratorManual/BestPractice/Realurl/Index.html
There are 3 ways explained there:
a basic one which still shows action and controller name as an URL path segment
an advanced example (the one Bernd Wilke is using in his sample as well)
a TypoScript solution to avoid controller and action name in URL
Option 2 can only be used if you show your detail news on a dedicated pages (separate page for list and detail view) as you configure a preset for a controller and action name for a special page (uid) - your news detail view.
Option 3 basically does the same as Option 2, but on a TypoScript level and it can be used in a case where list and detail view is on one single page.
Both options can / should be used in combination with the setting skipControllerAndAction = 1.
In case you want to use the basic setup. The postVarSets is on the same level as fixedPortsVars or preVars
Additional hint:
Do you use any other language than DE or EN as your default language? If so your default language has sys language uid of 0 and thus all good.
The default language usually has sys language uid of 0. If you do not need a default language path segment, you leave it out in our real url config thus it gets bypassed.
More info on language setup: https://github.com/dmitryd/typo3-realurl/wiki/Notes-for-Integrators#configuring-languages
RealUrl Doc:
https://github.com/dmitryd/typo3-realurl/wiki

Invalid parameter while creating adset

While creating an Adset in facebook-ads-sdk i get invalid parameter. I tried my best to track and resolve the problem but couldn't succeed. Please help. Following is the code snippet:
function adddSet($audienceid,$parentId,$accountId2,$campaignid,$productSetId){
try {
$adset = new AdSet(null, $accountId2);
$adset->setData(array(
AdSetFields::NAME => 'test',
AdSetFields::DAILY_BUDGET =>40000,
AdSetFields::BID_AMOUNT =>4000,
AdSetFields::BILLING_EVENT => BillingEvents::IMPRESSIONS,
AdSetFields::OPTIMIZATION_GOAL => OptimizationGoals::APP_INSTALLS,
AdSetFields::CAMPAIGN_ID => $campaignid,
AdSetFields::START_TIME => '2016-04-11T09:22:03+00:00',
AdSetFields::END_TIME =>'2016-04-20T09:22:03+00:00',
AdSetFields::TARGETING => (new TargetingSpecs())->setData(array(
TargetingSpecsFields::GEO_LOCATIONS => array(
'countries' => array('JP'),
'regions' => array(array('key' => '3886')),
'cities' => array(
array(
'key' => '2420605',
'radius' => 10,
'distance_unit' => 'mile',
),
),
),
TargetingSpecsFields::GENDERS => array(1),
TargetingSpecsFields::AGE_MIN => 20,
TargetingSpecsFields::AGE_MAX => 24,
TargetingSpecsFields::PAGE_TYPES => array(
PageTypes::MOBILE_FEED,
PageTypes::MOBILE_EXTERNAL,
),
)),
));
$adset->create(array(AdSet::STATUS_PARAM_NAME=>AdSet::STATUS_PAUSED));
}
catch(\FacebookAds\Http\Exception\RequestException $e){
echo $e->getMessage();
}
}
and get the following response:
Invalid parameter
This might help you to better understand exact error.
function adddSet($audienceid,$parentId,$accountId2,$campaignid,$productSetId){
try {
$adset = new AdSet(null, $accountId2);
$adset->setData(array(
AdSetFields::NAME => 'test',
AdSetFields::DAILY_BUDGET =>40000,
AdSetFields::BID_AMOUNT =>4000,
AdSetFields::BILLING_EVENT => BillingEvents::IMPRESSIONS,
AdSetFields::OPTIMIZATION_GOAL => OptimizationGoals::APP_INSTALLS,
AdSetFields::CAMPAIGN_ID => $campaignid,
AdSetFields::START_TIME => '2016-04-11T09:22:03+00:00',
AdSetFields::END_TIME =>'2016-04-20T09:22:03+00:00',
AdSetFields::TARGETING => (new TargetingSpecs())->setData(array(
TargetingSpecsFields::GEO_LOCATIONS => array(
'countries' => array('JP'),
'regions' => array(array('key' => '3886')),
'cities' => array(
array(
'key' => '2420605',
'radius' => 10,
'distance_unit' => 'mile',
),
),
),
TargetingSpecsFields::GENDERS => array(1),
TargetingSpecsFields::AGE_MIN => 20,
TargetingSpecsFields::AGE_MAX => 24,
TargetingSpecsFields::PAGE_TYPES => array(
PageTypes::MOBILE_FEED,
PageTypes::MOBILE_EXTERNAL,
),
)),
));
$adset->create(array(AdSet::STATUS_PARAM_NAME=>AdSet::STATUS_PAUSED));
}
catch(\FacebookAds\Http\Exception\AuthorizationException $e){
print_r($e->getResponse()->getBody());
}
}

Auth.net eCheck implementation using John Conde's AuthnetXML Class

I have an existing implementation of this class processing subscriptions by credit card but I now need to add the facility to accept payment by eCheck but I am unsure of how to change this portion of the code:
'payment' => array(
'creditCard' => array(
'cardNumber' => '4111111111111111',
'expirationDate' => '2016-08'
)
),
I have come up with the following from referencing the AIM guide pdf and AIM guide XML pdf
'payment' => array(
'bankAccount' => array( // x_method equivalent ?
'routingNumber' => '', // x_bank_aba_code equivalent ?
'accountNumber' => '', // x_bank_acct_num equivalent ?
'nameOnAccount' => '', // x_bank_acct_name equivalent ?
'bankName' => '', // x_bank_name equivalent ?
'echeckType' => 'WEB' // x_echeck_type equivalent
/*
x_bank_acct_type has no equivalent ?
*/
)
),
but there appears to be some discrepancies between the required fields?
Any pointers before I start on this would be greatly appreciated.
Looking at Authorize.Net's documentation this should work:
'payment' => array(
'bankAccount' => array(
'accountType' => '', // 'checking'
'routingNumber' => '',
'accountNumber' => '',
'nameOnAccount' => ''
)
),
Following on from John's answer this is the complete code I used to solve this for anyone finding this through a google search:
$xml->ARBCreateSubscriptionRequest(array(
'subscription' => array(
'name' => 'SubscriptionName',
'paymentSchedule' => array(
'interval' => array(
'length' => '1',
'unit' => 'months'
),
'startDate' => date('Y-m-d', time()), // Format: YYYY-MM-DD
'totalOccurrences' => '9999' // To submit a subscription with no end date (an ongoing subscription), this field must be submitted with a value of 9999
),
'amount' => $eCart1->GrandTotal(), // total monthly subscription
'payment' => array(
'bankAccount' => array(
'accountType' => ((isset($_POST["accountType"]))?$_POST["accountType"]:""), // options available are checking or businessChecking in this instance
'routingNumber' => ((isset($_POST["routingNumber"]))?$_POST["routingNumber"]:""),
'accountNumber' => ((isset($_POST["accountNumber"]))?$_POST["accountNumber"]:""),
'nameOnAccount' => ((isset($_POST["nameOnAccount"]))?$_POST["nameOnAccount"]:""),
'echeckType' => ((isset($_POST["echeckType"]))?$_POST["echeckType"]:"") // if businessChecking is chosen then 'CCD' else 'WEB'
)
),
'customer' => array(
'id' => "'".$_SESSION['clientID']."'",
'email' => "'".((isset($_POST["email"]))?$_POST["email"]:"")."'"
),
'billTo' => array(
'firstName' => "'".((isset($_POST["firstname"]))?$_POST["firstname"]:"")."'",
'lastName' => "'".((isset($_POST["lastname"]))?$_POST["lastname"]:"")."'",
'company' => "'".((isset($_POST["company"]))?$_POST["company"]:"")."'",
'address' => "'".((isset($_POST["street1"]))?$_POST["street1"]:"")."'",
'city' => "'".((isset($_POST["city"]))?$_POST["city"]:"")."'",
'state' => "'".((isset($_POST["state_province"]))?$_POST["state_province"]:"")."'",
'zip' => "'".((isset($_POST["postcode"]))?$_POST["postcode"]:"")."'"
)
)
));

Create DynamoDB table with Global Secondary Index

I'm new to AWS DynamoDB and to nosql in general, and I'm having problem with table creation.
I'm trying to create a table named User with the following Attributes:
UserId (HASH)
OSType (RANGE)
MSISDN
IMSI
DeviceID
I need to query the table not only by UserId, but also by the following fields:
MSISDN
IMSI
DeviceID
My Logic is as follows:
Query the table by the UserId field.
If the query returned no results create a new one, but check that there isn't other users with the same MSISDN filed OR the same IMSI field OR the same DeviceID field.
After reading the manual about LSI/GSI i'm having difficulties understating how to create the table and define those indexes.
This is the code i'm tring to execute to creater the table using PHP+AWS SDK:
$client->createTable(array(
'TableName' => 'User',
'AttributeDefinitions' => array(
array('AttributeName' => 'UserId', 'AttributeType' => 'S'),
array('AttributeName' => 'OSType', 'AttributeType' => 'S'),
array('AttributeName' => 'MSISDN', 'AttributeType' => 'S'),
array('AttributeName' => 'IMSI', 'AttributeType' => 'S'),
array('AttributeName' => 'DeviceID', 'AttributeType' => 'S'),
),
'KeySchema' => array(
array('AttributeName' => 'UserId', 'KeyType' => 'HASH'),
array('AttributeName' => 'OSType', 'KeyType' => 'RANGE')
),
'GlobalSecondaryIndexes' => array(
array(
'IndexName' => 'IMSIIndex',
'KeySchema' => array(
array('AttributeName' => 'IMSI', 'KeyType' => 'HASH')
),
'Projection' => array(
'ProjectionType' => 'KEYS_ONLY',
),
'ProvisionedThroughput' => array(
'ReadCapacityUnits' => 10,
'WriteCapacityUnits' => 10
)
),
array(
'IndexName' => 'MSISDNIndex',
'KeySchema' => array(
array('AttributeName' => 'MSISDN', 'KeyType' => 'HASH')
),
'Projection' => array(
'ProjectionType' => 'KEYS_ONLY',
),
'ProvisionedThroughput' => array(
'ReadCapacityUnits' => 10,
'WriteCapacityUnits' => 10
)
),
array(
'IndexName' => 'DeviceIDIndex',
'KeySchema' => array(
array('AttributeName' => 'DeviceID', 'KeyType' => 'HASH')
),
'Projection' => array(
'ProjectionType' => 'KEYS_ONLY',
),
'ProvisionedThroughput' => array(
'ReadCapacityUnits' => 10,
'WriteCapacityUnits' => 10
)
),
),
'ProvisionedThroughput' => array(
'ReadCapacityUnits' => 50,
'WriteCapacityUnits' => 50
)
));
I'm getting this error:
PHP Fatal error: Uncaught Aws\DynamoDb\Exception\ValidationException: AWS Error Code: ValidationException, Status Code: 400, AWS Request ID: 70LGIARTTQF90S8P0HVRUKSJ27VV4KQNSO5AEMVJF66Q9ASUAAJG, AWS Error Type: client, AWS Error Message: One or more parameter values were invalid: Number of attributes in KeySchema does not exactly match number of attributes defined in AttributeDefinitions, User-Agent: aws-sdk-php2/2.4.11 Guzzle/3.7.4 curl/7.29.0 PHP/5.4.14
Please help me understand what am I doing wrong. I want to create the table with GSI, but I just can't comprehend the essence of secondary index in DynamoDB :(
Only attributes that are included in local and global index should be defined in the AttributeDefinitions section.
This should work:
$client->createTable(array(
'TableName' => 'User',
'AttributeDefinitions' => array(
array('AttributeName' => 'UserId', 'AttributeType' => 'S'),
array('AttributeName' => 'OSType', 'AttributeType' => 'S')
),
'KeySchema' => array(
array('AttributeName' => 'UserId', 'KeyType' => 'HASH'),
array('AttributeName' => 'OSType', 'KeyType' => 'RANGE')
),
'GlobalSecondaryIndexes' => array(
array(
'IndexName' => 'IMSIIndex',
'KeySchema' => array(
array('AttributeName' => 'IMSI', 'KeyType' => 'HASH')
),
'Projection' => array(
'ProjectionType' => 'KEYS_ONLY',
),
'ProvisionedThroughput' => array(
'ReadCapacityUnits' => 10,
'WriteCapacityUnits' => 10
)
),
array(
'IndexName' => 'MSISDNIndex',
'KeySchema' => array(
array('AttributeName' => 'MSISDN', 'KeyType' => 'HASH')
),
'Projection' => array(
'ProjectionType' => 'KEYS_ONLY',
),
'ProvisionedThroughput' => array(
'ReadCapacityUnits' => 10,
'WriteCapacityUnits' => 10
)
),
array(
'IndexName' => 'DeviceIDIndex',
'KeySchema' => array(
array('AttributeName' => 'DeviceID', 'KeyType' => 'HASH')
),
'Projection' => array(
'ProjectionType' => 'KEYS_ONLY',
),
'ProvisionedThroughput' => array(
'ReadCapacityUnits' => 10,
'WriteCapacityUnits' => 10
)
),
),
'ProvisionedThroughput' => array(
'ReadCapacityUnits' => 50,
'WriteCapacityUnits' => 50
)));
Hope that helps

Categories