amazon integration refactor

This commit is contained in:
Gabriel Bazán 2016-07-21 11:18:48 -03:00 committed by Gustavo Maximiliano Cortez
commit 6dff2840c8
No known key found for this signature in database
GPG key ID: 15EDAD8D9F2EB1AF
12 changed files with 336 additions and 454 deletions

View file

@ -9,12 +9,6 @@
</a> </a>
</section> </section>
<section class="right-small">
<a class="p10" ui-sref="buyAmazon">
<i class="fi-shopping-cart size-24"></i>
</a>
</section>
<section class="middle tab-bar-section"> <section class="middle tab-bar-section">
<h1 class="title ellipsis"> <h1 class="title ellipsis">
Gift cards Gift cards
@ -32,16 +26,16 @@
Sandbox version. Only for testing purpose Sandbox version. Only for testing purpose
</div> </div>
<div class="m20t text-center" ng-click="amazon.init()"> <div class="m20t text-center" ng-click="amazon.updatePendingGiftCards()">
<img src="img/GCs-logo-cllb.png" alt="Amazon.com Gift Card" width="200"> <img src="img/GCs-logo-cllb.png" alt="Amazon.com Gift Card" width="200">
<div class="size-10 m5t text-gray"><b>Only</b> redeemable on www.amazon.com (USA website)</div> <div class="size-10 m5t text-gray"><b>Only</b> redeemable on www.amazon.com (USA website)</div>
</div> </div>
<div ng-if="!amazon.giftCards" class="m20t text-center size-12"> <div ng-if="!giftCards" class="m20t text-center size-12">
<div class="row"> <div class="row">
<div class="columns"> <div class="columns">
<button class="m20t button black round expand" <button class="m20t button black round expand"
ui-sref="buyAmazon"> ui-sref="buyAmazon">
Buy now Buy now
</button> </button>
@ -49,26 +43,39 @@
</div> </div>
<div class="text-left p10h m30v"> <div class="text-left p10h m30v">
Amazon.com Gift Cards never expire and can be redeemed towards millions of items at Amazon.com Gift Cards never expire and can be redeemed towards millions of items at
<a ng-click="$root.openExternalLink('https://www.amazon.com')">www.amazon.com</a> <a ng-click="$root.openExternalLink('https://www.amazon.com')">www.amazon.com</a>
</div> </div>
</div> </div>
<div ng-if="amazon.giftCards"> <div class="p20t" ng-if="giftCards">
<ul class="no-bullet m0 size-14">
<li class="line-b line-t p10 pointer" href ui-sref="buyAmazon">
<i class="fi-shopping-cart size-24 p10 vm dib"></i>
<span class="m10 text-normal text-bold">Buy Gift Card</span>
<span class="right text-gray p15t">
<i class="icon-arrow-right3 size-24 right"></i>
</span>
</li>
</ul>
<h4 class="title">Your cards</h4> <h4 class="title">Your cards</h4>
<div ng-repeat="(id, item) in amazon.giftCards | orderObjectBy:'date':true track by $index" <div ng-repeat="(id, item) in giftCards | orderObjectBy:'date':true track by $index"
ng-click="amazon.openCardModal(item)" ng-click="amazon.openCardModal(item)"
class="row collapse last-transactions-content size-12"> class="row collapse last-transactions-content size-12">
<div class="large-2 medium-2 small-2 columns"> <div class="large-2 medium-2 small-2 columns">
<img src="img/a-smile_color_btn.png" alt="{{id}}" width="40"> <img src="img/a-smile_color_btn.png" alt="{{id}}" width="40">
</div> </div>
<div class="large-4 medium-4 small-4 columns m5t size-18"> <div class="large-4 medium-4 small-4 columns m5t size-18" ng-if="item.claimCode">
{{item.cardInfo.value.amount | currency : '$ ' : 2}} {{item.amount | currency : '$ ' : 2}}
</div>
<div class="large-4 medium-4 small-4 columns m5t size-18" ng-if="!item.claimCode">
-
</div> </div>
<div class="large-5 medium-5 small-5 columns text-right m10t"> <div class="large-5 medium-5 small-5 columns text-right m10t">
<span class="text-warning" ng-if="item.status == 'FAILURE'">Error</span> <span class="text-warning" ng-if="item.status == 'FAILURE'">Error</span>
<span class="text-secondary" ng-if="item.status == 'RESEND'">Resend is required</span> <span class="text-secondary" ng-if="item.status == 'RESEND'">Resend is required</span>
<span class="text-gray" ng-if="item.status == 'SUCCESS'">{{item.date * 1000 | amTimeAgo}}</span> <span class="text-gray" ng-if="item.status == 'PENDING'">Pending to confirmation</span>
<span class="text-gray" ng-if="item.status == 'SUCCESS'">{{item.date | amTimeAgo}}</span>
</div> </div>
<div class="large-1 medium-1 small-1 columns text-right m10t"> <div class="large-1 medium-1 small-1 columns text-right m10t">
<i class="icon-arrow-right3 size-18"></i> <i class="icon-arrow-right3 size-18"></i>

View file

@ -1,5 +1,5 @@
<div <div
class="topbar-container" class="topbar-container"
ng-include="'views/includes/topbar.html'" ng-include="'views/includes/topbar.html'"
ng-init="titleSection='Buy'; goBackToState = 'amazon'; noColor = true"> ng-init="titleSection='Buy'; goBackToState = 'amazon'; noColor = true">
</div> </div>
@ -18,14 +18,14 @@
There was an error when trying to buy gift card, but the funds were sent to BitPay Invoice. Please, contact There was an error when trying to buy gift card, but the funds were sent to BitPay Invoice. Please, contact
BitPay to refund your bitcoin BitPay to refund your bitcoin
<div class="p10 m10t"> <div class="p10 m10t">
Amount: {{buy.errorInfo.amount}} {{buy.errorInfo.currencyCode}}<br> Amount: {{buy.errorInfo.amount}} {{buy.errorInfo.currency}}<br>
BitPay Invoice ID: {{buy.errorInfo.bitpayInvoiceId}}. BitPay Invoice ID: {{buy.errorInfo.invoiceId}}.
</div> </div>
<div class="text-center"> <div class="text-center">
<a ng-click="$root.openExternalLink(buy.errorInfo.bitpayInvoiceUrl)">Open invoice</a> <a ng-click="$root.openExternalLink(buy.errorInfo.invoiceUrl)">Open invoice</a>
</div> </div>
</div> </div>
</div> </div>
<div class="text-center"> <div class="text-center">
<img src="img/a_generic.jpg" alt="Amazon.com Gift Card" width="180"> <img src="img/a_generic.jpg" alt="Amazon.com Gift Card" width="180">
@ -35,8 +35,8 @@
</div> </div>
<form <form
class="m30v" class="m30v"
name="buyAmazonForm" name="buyAmazonForm"
ng-submit="buy.createTx()" ng-submit="buy.createTx()"
novalidate> novalidate>
<label> <label>
@ -51,22 +51,22 @@
<a class="postfix button black">USD</a> <a class="postfix button black">USD</a>
</div> </div>
<div <div
class="m10b" class="m10b"
ng-click="openWalletsModal(buy.allWallets)"> ng-click="openWalletsModal(buy.allWallets)">
<label>Pay From Copay Wallet</label> <label>Pay From Copay Wallet</label>
<div class="input"> <div class="input">
<input type="text" id="address" name="address" ng-disabled="buy.selectedWalletId" <input type="text" id="address" name="address" ng-disabled="buy.selectedWalletId"
ng-attr-placeholder="{{'Choose your source wallet'}}" ng-attr-placeholder="{{'Choose your source wallet'}}"
ng-model="buy.selectedWalletName" required> ng-model="buy.selectedWalletName" required>
<a class="postfix size-12 m0 text-gray"> <a class="postfix size-12 m0 text-gray">
<i class="icon-wallet size-18"></i> <i class="icon-wallet size-18"></i>
</a> </a>
</div> </div>
</div> </div>
<div class="input m20t"> <div class="input m20t">
<input class="button black round expand" <input class="button black round expand"
ng-disabled="!buy.selectedWalletId || !fiat" ng-disabled="!buy.selectedWalletId || !fiat"
type="submit" value="Buy now"> type="submit" value="Buy now">
</div> </div>
@ -75,7 +75,7 @@
</div> </div>
<div class="m10t" ng-show="buy.giftCard"> <div class="m10t" ng-show="buy.giftCard">
<div class="m10h" ng-show="buy.giftCard.status != 'SUCCESS'"> <div class="m10h" ng-show="buy.giftCard.status != 'SUCCESS' && buy.giftCard.status != 'PENDING'">
<h1 class="text-center">Gift card could not be created</h1> <h1 class="text-center">Gift card could not be created</h1>
<div class="box-notification m20b"> <div class="box-notification m20b">
<span class="text-warning"> <span class="text-warning">
@ -88,38 +88,41 @@
resolved retrying the request from your list of cards resolved retrying the request from your list of cards
</span> </span>
<span ng-show="buy.giftCard.status == 'FAILURE'"> <span ng-show="buy.giftCard.status == 'FAILURE'">
This failure could not be recoverable. Request your refund from your list of cards This failure could not be recoverable. Request your refund from your list of cards
</span> </span>
<button class="m20t button outline round dark-gray expand" ng-click="$root.go('amazon')"> <button class="m20t button outline round dark-gray expand" ng-click="$root.go('amazon')">
Back Back
</button> </button>
</div> </div>
</div> </div>
<div ng-show="buy.giftCard.status == 'SUCCESS'"> <div ng-show="buy.giftCard.status == 'SUCCESS'">
<div class="size-12 m10h"> <div class="size-12 m10h">
Thank you for participating in the BitPay offer. It is our pleasure to send Thank you for participating in the BitPay offer. It is our pleasure to send
you this Amazon.com Gift Card* that can be redeemed towards millions of items at you this Amazon.com Gift Card* that can be redeemed towards millions of items at
<a ng-click="$root.openExternalLink('https://www.amazon.com')">www.amazon.com</a>. You may want to print this screen <a ng-click="$root.openExternalLink('https://www.amazon.com')">www.amazon.com</a>. You may want to print this screen
for easy reference later--you&rsquo;ll need the gift card claim code below for easy reference later--you&rsquo;ll need the gift card claim code below
</div> </div>
<div class="oh m20t size-12 text-center"> <div class="oh m20t size-12 text-center">
<img class="m10h" src="img/a_generic.jpg" alt="Amazon.com Gift Cards" width="200"> <img class="m10h" src="img/a_generic.jpg" alt="Amazon.com Gift Cards" width="200">
<div class="m10t size-14"> <div class="m10t size-14">
Gift Card Amount: Gift Card Amount:
<span class="text-bold"> <span class="text-bold">
{{buy.giftCard.cardInfo.value.amount | currency : '$ ' : 2 }} {{buy.giftCard.amount | currency : '$ ' : 2 }}
</span> </span>
</div> </div>
<div class="size-14"> <div class="size-14">
Claim code: <span class="text-bold enable_text_select">{{buy.giftCard.gcClaimCode}}</span> Claim code: <span class="text-bold enable_text_select">{{buy.giftCard.claimCode}}</span>
</div> </div>
<div class="m10t"> <div class="m10t">
<button class="button black round tiny" <button class="button black round tiny"
ng-click="$root.openExternalLink('https://www.amazon.com/gc/redeem?claimCode=' + buy.giftCard.gcClaimCode, '_system')"> ng-click="$root.openExternalLink('https://www.amazon.com/gc/redeem?claimCode=' + buy.giftCard.claimCode, '_system')">
Redeem Now Redeem Now
</button> </button>
</div> </div>
<div class="size-12 m10t text-center">
<a ng-click="$root.openExternalLink(buy.giftCard.invoiceUrl)">See invoice</a>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -129,11 +132,11 @@
reseller of Amazon.com Gift Cards. Except as required by law, GCs cannot be transferred for value or redeemed for cash. reseller of Amazon.com Gift Cards. Except as required by law, GCs cannot be transferred for value or redeemed for cash.
GCs may be used only for purchases of eligible goods at Amazon.com or certain of its affiliated websites. Purchases are GCs may be used only for purchases of eligible goods at Amazon.com or certain of its affiliated websites. Purchases are
deducted from the GC balance. To redeem or view a GC balance, visit &ldquo;Your Account&rdquo; at Amazon.com. Amazon is deducted from the GC balance. To redeem or view a GC balance, visit &ldquo;Your Account&rdquo; at Amazon.com. Amazon is
not responsible if a GC is lost, stolen, destroyed or used without permission. See not responsible if a GC is lost, stolen, destroyed or used without permission. See
<a ng-click="$root.openExternalLink('https://www.amazon.com/gc-legal')">www.amazon.com/gc-legal</a> for complete terms, <a ng-click="$root.openExternalLink('https://www.amazon.com/gc-legal')">www.amazon.com/gc-legal</a> for complete terms,
restrictions and exceptions. For any other questions, see restrictions and exceptions. For any other questions, see
<a ng-click="$root.openExternalLink('https://www.amazon.com/gc')">www.amazon.com/gc</a>. GCs are issued <a ng-click="$root.openExternalLink('https://www.amazon.com/gc')">www.amazon.com/gc</a>. GCs are issued
by ACI Gift Cards, Inc., a Washington corporation. All Amazon &reg;, &trade; &amp; &copy; are IP of by ACI Gift Cards, Inc., a Washington corporation. All Amazon &reg;, &trade; &amp; &copy; are IP of
Amazon.com, Inc. or its affiliates. No expiration date or service fees. Amazon.com, Inc. or its affiliates. No expiration date or service fees.
</div> </div>

View file

@ -13,45 +13,48 @@
</section> </section>
</nav> </nav>
<ion-content overflow-scroll="true"> <ion-content class="has-header" overflow-scroll="true">
<div class="modal-content fix-modals-touch"> <div class="modal-content">
<div class="header-modal text-center"> <div class="header-modal text-center">
<img src="img/a_generic.jpg" alt="Amazon.com Gift Card" width="230" ng-click="refreshGiftCard()"> <img src="img/a_generic.jpg" alt="Amazon.com Gift Card" width="230" ng-click="refreshGiftCard()">
<div ng-show="card.gcClaimCode"> <div ng-show="card.claimCode">
<div class="m10t"> <div class="m10t">
Gift Card Amount: Gift Card Amount:
<span class="text-bold"> <span class="text-bold">
{{card.cardInfo.value.amount | currency : '$ ' : 2}} {{card.amount | currency : '$ ' : 2}}
</span> </span>
</div> </div>
<div> <div>
Claim code: <span class="text-bold enable_text_select">{{card.gcClaimCode}}</span> Claim code: <span class="text-bold enable_text_select">{{card.claimCode}}</span>
</div> </div>
<div class="m10t" ng-show="card.cardInfo.cardStatus == 'Fulfilled'"> <div class="m10t" ng-show="card.cardStatus == 'Fulfilled'">
<button class="button black round tiny" <button class="button black round tiny"
ng-click="$root.openExternalLink('https://www.amazon.com/gc/redeem?claimCode=' + card.gcClaimCode, '_system')"> ng-click="$root.openExternalLink('https://www.amazon.com/gc/redeem?claimCode=' + card.claimCode, '_system')">
Redeem Now Redeem Now
</button> </button>
</div> </div>
</div>
<div class="text-warning text-center" ng-if="card.cardInfo.cardStatus == 'RefundedToPurchaser'"> <div ng-show="!card.claimCode">
Cancelled (Refunded) <div class="m10t">
</div> Status:
<span class="text-bold">
<div class="size-12 m10t text-center"> PENDING
<a ng-click="$root.openExternalLink(card.bitpayInvoiceUrl)">See invoice</a> </span>
</div> </div>
</div> </div>
<div class="size-12 m10t text-center">
<a ng-click="$root.openExternalLink(card.invoiceUrl)">See invoice</a>
</div>
</div> </div>
<div class="box-notification m20b" ng-show="error" ng-click="error = null"> <div class="box-notification m20b" ng-show="error" ng-click="error = null">
<span class="text-warning"> <span class="text-warning">
{{error}} {{error}}
</span> </span>
</div> </div>
<div class="text-center size-12" ng-show="card.status != 'SUCCESS'"> <div class="text-center size-12" ng-show="card.status != 'SUCCESS'">
<div ng-show="card.status == 'RESEND'"> <div ng-show="card.status == 'RESEND'">
@ -72,20 +75,17 @@
reseller of Amazon.com Gift Cards. Except as required by law, GCs cannot be transferred for value or redeemed for cash. reseller of Amazon.com Gift Cards. Except as required by law, GCs cannot be transferred for value or redeemed for cash.
GCs may be used only for purchases of eligible goods at Amazon.com or certain of its affiliated websites. Purchases are GCs may be used only for purchases of eligible goods at Amazon.com or certain of its affiliated websites. Purchases are
deducted from the GC balance. To redeem or view a GC balance, visit &ldquo;Your Account&rdquo; at Amazon.com. Amazon is deducted from the GC balance. To redeem or view a GC balance, visit &ldquo;Your Account&rdquo; at Amazon.com. Amazon is
not responsible if a GC is lost, stolen, destroyed or used without permission. See not responsible if a GC is lost, stolen, destroyed or used without permission. See
<a ng-click="$root.openExternalLink('https://www.amazon.com/gc-legal')">www.amazon.com/gc-legal</a> for complete terms, <a ng-click="$root.openExternalLink('https://www.amazon.com/gc-legal')">www.amazon.com/gc-legal</a> for complete terms,
restrictions and exceptions. For any other questions, see restrictions and exceptions. For any other questions, see
<a ng-click="$root.openExternalLink('https://www.amazon.com/gc')">www.amazon.com/gc</a>. GCs are issued <a ng-click="$root.openExternalLink('https://www.amazon.com/gc')">www.amazon.com/gc</a>. GCs are issued
by ACI Gift Cards, Inc., a Washington corporation. All Amazon &reg;, &trade; &amp; &copy; are IP of by ACI Gift Cards, Inc., a Washington corporation. All Amazon &reg;, &trade; &amp; &copy; are IP of
Amazon.com, Inc. or its affiliates. No expiration date or service fees. Amazon.com, Inc. or its affiliates. No expiration date or service fees.
</div> </div>
<ul class="no-bullet size-14 m30v text-center"> <ul class="no-bullet size-14 m30v text-center">
<li class="line-b p10 oh pointer" ng-show="card.status == 'SUCCESS' && card.cardInfo.cardStatus == 'Fulfilled'" ng-click="cancelGiftCard()"> <li class="line-b p10 oh pointer" ng-show="card.status == 'FAILURE' || card.cardStatus == 'RefundedToPurchaser'
<span class="text-warning">Cancel gift card</span> || card.cardStatus == 'Expired'" ng-click="remove()">
</li>
<li class="line-b p10 oh pointer" ng-show="card.status == 'FAILURE' || card.cardInfo.cardStatus == 'RefundedToPurchaser'
|| card.cardInfo.cardStatus == 'Expired'" ng-click="remove()">
<span class="text-warning">Remove gift card</span> <span class="text-warning">Remove gift card</span>
</li> </li>
</ul> </ul>

View file

@ -11,7 +11,8 @@
</h1> </h1>
</ion-header-bar> </ion-header-bar>
<ion-content> <ion-content ng-style="{'background-color': '#F6F7F9'}">
<div class="modal-content"> <div class="modal-content">
<div class="box-notification text-center size-12 text-warning m10t" ng-show="error"> <div class="box-notification text-center size-12 text-warning m10t" ng-show="error">
<i class="fi-error"></i> {{error}} <i class="fi-error"></i> {{error}}

View file

@ -25,7 +25,6 @@
</div> </div>
</div> </div>
<div class="oh" ng-show="!index.noFocusedWallet"> <div class="oh" ng-show="!index.noFocusedWallet">
<!-- <!--

View file

@ -1,24 +1,70 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('amazonController', angular.module('copayApp.controllers').controller('amazonController',
function($scope, $timeout, $ionicModal, lodash, configService, amazonService) { function($scope, $timeout, $ionicModal, $log, lodash, bwcError, configService, amazonService) {
this.init = function() { this.init = function() {
var self = this; var self = this;
var network = configService.getSync().amazon.testnet ? 'testnet' : 'livenet'; var network = configService.getSync().amazon.testnet ? 'testnet' : 'livenet';
self.sandbox = network == 'testnet' ? true : false; self.sandbox = network == 'testnet' ? true : false;
amazonService.setCredentials(network); amazonService.setCredentials(network);
amazonService.getGiftCards(function(err, gcds) { amazonService.getPendingGiftCards(function(err, gcds) {
if (err) { if (err) {
self.error = err; self.error = err;
return; return;
} }
self.giftCards = lodash.isEmpty(gcds) ? null : gcds; $scope.giftCards = lodash.isEmpty(gcds) ? null : gcds;
$timeout(function() { $timeout(function() {
$scope.$digest(); $scope.$digest();
}); });
}); });
}; this.updatePendingGiftCards();
}
this.updatePendingGiftCards = lodash.debounce(function() {
amazonService.getPendingGiftCards(function(err, gcds) {
lodash.forEach(gcds, function(dataFromStorage) {
if (dataFromStorage.status == 'PENDING') {
$log.debug("creating gift card");
amazonService.createGiftCard(dataFromStorage, function(err, giftCard) {
if (err) {
$log.debug(bwcError.msg(err));
return;
}
if (giftCard.status != 'PENDING') {
var newData = {};
lodash.merge(newData, dataFromStorage, giftCard);
if (newData.status == 'expired') {
amazonService.savePendingGiftCard(newData, {
remove: true
}, function(err) {
return;
});
}
amazonService.savePendingGiftCard(newData, null, function(err) {
$log.debug("Saving new gift card");
amazonService.getPendingGiftCards(function(err, gcds) {
if (err) {
self.error = err;
return;
}
$scope.giftCards = gcds;
$timeout(function() {
$scope.$digest();
});
});
});
} else $log.debug("pending gift card not available yet");
});
}
});
});
}, 1000);
this.openCardModal = function(card) { this.openCardModal = function(card) {
var self = this; var self = this;

View file

@ -1,7 +1,7 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('buyAmazonController', angular.module('copayApp.controllers').controller('buyAmazonController',
function($rootScope, $scope, $ionicModal, $log, $timeout, lodash, profileService, bwcError, configService, walletService, fingerprintService, amazonService, ongoingProcess) { function($rootScope, $scope, $ionicModal, $log, $timeout, $state, lodash, profileService, bwcError, configService, walletService, fingerprintService, amazonService, ongoingProcess) {
var self = this; var self = this;
var client; var client;
@ -17,11 +17,9 @@ angular.module('copayApp.controllers').controller('buyAmazonController',
this.init = function() { this.init = function() {
var network = configService.getSync().amazon.testnet ? 'testnet' : 'livenet'; var network = configService.getSync().amazon.testnet ? 'testnet' : 'livenet';
amazonService.setCredentials(network); amazonService.setCredentials(network);
amazonService.healthCheckRequest();
amazonService.initUuid();
self.allWallets = profileService.getWallets(network, 1); self.allWallets = profileService.getWallets(network, 1);
client = profileService.focusedClient; client = profileService.focusedClient;
if (client && client.credentials.m == 1) { if (client && client.credentials.m == 1 && client.credentials.network == network) {
$timeout(function() { $timeout(function() {
self.selectedWalletId = client.credentials.walletId; self.selectedWalletId = client.credentials.walletId;
self.selectedWalletName = client.credentials.walletName; self.selectedWalletName = client.credentials.walletName;
@ -62,9 +60,8 @@ angular.module('copayApp.controllers').controller('buyAmazonController',
var currency_code = configService.getSync().amazon.testnet ? window.amazon_sandbox_currency_code : window.amazon_currency_code; var currency_code = configService.getSync().amazon.testnet ? window.amazon_sandbox_currency_code : window.amazon_currency_code;
var dataSrc = { var dataSrc = {
price: $scope.fiat,
currency: currency_code, currency: currency_code,
orderId: self.selectedWalletName amount: $scope.fiat
}; };
var outputs = []; var outputs = [];
var config = configService.getSync(); var config = configService.getSync();
@ -74,8 +71,7 @@ angular.module('copayApp.controllers').controller('buyAmazonController',
ongoingProcess.set('Processing Transaction...', true); ongoingProcess.set('Processing Transaction...', true);
$timeout(function() { $timeout(function() {
amazonService.createBitPayInvoice(dataSrc, function(err, dataInvoice) {
amazonService.createBitPayInvoice(dataSrc, function(err, data) {
if (err) { if (err) {
ongoingProcess.set('Processing Transaction...', false); ongoingProcess.set('Processing Transaction...', false);
self.error = bwcError.msg(err); self.error = bwcError.msg(err);
@ -85,79 +81,131 @@ angular.module('copayApp.controllers').controller('buyAmazonController',
return; return;
} }
var address, comment, amount; amazonService.getBitPayInvoice(dataInvoice.invoiceId, function(err, invoice) {
address = data.data.bitcoinAddress;
amount = parseInt((data.data.btcPrice * 100000000).toFixed(0));
comment = 'Amazon.com Gift Card';
outputs.push({
'toAddress': address,
'amount': amount,
'message': comment
});
var txp = {
toAddress: address,
amount: amount,
outputs: outputs,
message: comment,
payProUrl: null,
excludeUnconfirmedUtxos: configWallet.spendUnconfirmed ? false : true,
feeLevel: walletSettings.feeLevel || 'normal'
};
walletService.createTx(client, txp, function(err, createdTxp) {
ongoingProcess.set('Processing Transaction...', false);
if (err) { if (err) {
ongoingProcess.set('Processing Transaction...', false);
self.error = bwcError.msg(err); self.error = bwcError.msg(err);
$timeout(function() { $timeout(function() {
$scope.$digest(); $scope.$digest();
}); });
return; return;
} }
$scope.$emit('Local/NeedsConfirmation', createdTxp, function(accept) {
if (accept) { var address, comment, amount;
self.confirmTx(createdTxp, function(err, tx) {
if (err) { address = invoice.bitcoinAddress;
ongoingProcess.set('Processing Transaction...', false); amount = parseInt((invoice.btcPrice * 100000000).toFixed(0));
self.error = bwcError.msg(err); comment = 'Amazon.com Gift Card';
$timeout(function() {
$scope.$digest(); outputs.push({
}); 'toAddress': address,
return; 'amount': amount,
} 'message': comment
var gift = { });
amount: dataSrc.price,
currencyCode: dataSrc.currency, var txp = {
bitpayInvoiceId: data.data.id, toAddress: address,
bitpayInvoiceUrl: data.data.url amount: amount,
}; outputs: outputs,
ongoingProcess.set('Processing Transaction...', true); message: comment,
amazonService.createGiftCard(gift, function(err, giftCard) { payProUrl: null,
ongoingProcess.set('Processing Transaction...', false); excludeUnconfirmedUtxos: configWallet.spendUnconfirmed ? false : true,
feeLevel: walletSettings.feeLevel || 'normal'
};
walletService.createTx(client, txp, function(err, createdTxp) {
ongoingProcess.set('Processing Transaction...', false);
if (err) {
self.error = bwcError.msg(err);
$timeout(function() {
$scope.$digest();
});
return;
}
$scope.$emit('Local/NeedsConfirmation', createdTxp, function(accept) {
if (accept) {
self.confirmTx(createdTxp, function(err, tx) {
if (err) { if (err) {
ongoingProcess.set('Processing Transaction...', false);
self.error = bwcError.msg(err); self.error = bwcError.msg(err);
self.errorInfo = gift;
$timeout(function() { $timeout(function() {
$scope.$digest(); $scope.$digest();
}); });
return; return;
} }
amazonService.setAmountByDay(dataSrc.price); var count = 0;
self.giftCard = giftCard; ongoingProcess.set('Processing Transaction...', true);
$timeout(function() {
$scope.$digest(); dataSrc.accessKey = dataInvoice.accessKey;
}); dataSrc.invoiceId = invoice.id;
dataSrc.invoiceUrl = invoice.url;
dataSrc.invoiceTime = invoice.invoiceTime;
self.debounceCreate(count, dataSrc);
}); });
}); }
} });
}); });
}); });
}); });
}, 100); }, 100);
}; };
self.debounceCreate = lodash.throttle(function(count, dataSrc) {
self.debounceCreateGiftCard(count, dataSrc);
}, 8000, {
'leading': true
});
self.debounceCreateGiftCard = function(count, dataSrc) {
amazonService.createGiftCard(dataSrc, function(err, giftCard) {
$log.debug("creating gift card " + count);
if (err) {
ongoingProcess.set('Processing Transaction...', false);
self.error = bwcError.msg(err);
self.errorInfo = dataSrc;
$timeout(function() {
$scope.$digest();
});
return;
}
if (giftCard.status == 'PENDING' && count < 3) {
$log.debug("pending gift card not available yet");
self.debounceCreate(count + 1, dataSrc, dataSrc);
return;
}
var now = moment().unix();
var newData = giftCard;
newData['invoiceId'] = dataSrc.invoiceId;
newData['accessKey'] = dataSrc.accessKey;
newData['invoiceUrl'] = dataSrc.invoiceUrl;
newData['amount'] = dataSrc.amount;
newData['date'] = dataSrc.invoiceTime || now;
if (newData.status == 'expired') {
amazonService.savePendingGiftCard(newData, {
remove: true
}, function(err) {
return;
});
}
amazonService.savePendingGiftCard(newData, null, function(err) {
ongoingProcess.set('Processing Transaction...', false);
$log.debug("Saving new gift card with status: " + newData.status);
self.giftCard = newData;
if (newData.status == 'PENDING') $state.transitionTo('amazon');
$timeout(function() {
$scope.$digest();
});
});
});
}
this.confirmTx = function(txp, cb) { this.confirmTx = function(txp, cb) {
fingerprintService.check(client, function(err) { fingerprintService.check(client, function(err) {

View file

@ -1,6 +1,7 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, $ionicScrollDelegate, $ionicPopup, $ionicSideMenuDelegate, latestReleaseService, feeService, bwcService, pushNotificationsService, lodash, go, profileService, configService, rateService, storageService, addressService, gettext, gettextCatalog, amMoment, addonManager, bwcError, txFormatService, uxLanguage, glideraService, coinbaseService, platformInfo, addressbookService, openURLService, ongoingProcess) { angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, $ionicScrollDelegate, $ionicPopup, $ionicSideMenuDelegate, $httpBackend, latestReleaseService, feeService, bwcService, pushNotificationsService, lodash, go, profileService, configService, rateService, storageService, addressService, gettext, gettextCatalog, amMoment, addonManager, bwcError, txFormatService, uxLanguage, glideraService, coinbaseService, amazonService, platformInfo, addressbookService, openURLService, ongoingProcess) {
var self = this; var self = this;
var SOFT_CONFIRMATION_LIMIT = 12; var SOFT_CONFIRMATION_LIMIT = 12;
var errors = bwcService.getErrors(); var errors = bwcService.getErrors();
@ -1041,10 +1042,6 @@ angular.module('copayApp.controllers').controller('indexController', function($r
}); });
}; };
self.initAmazon = function() {
self.amazonEnabled = configService.getSync().amazon.enabled;
};
self.initGlidera = function(accessToken) { self.initGlidera = function(accessToken) {
self.glideraEnabled = configService.getSync().glidera.enabled; self.glideraEnabled = configService.getSync().glidera.enabled;
self.glideraTestnet = configService.getSync().glidera.testnet; self.glideraTestnet = configService.getSync().glidera.testnet;
@ -1394,6 +1391,15 @@ angular.module('copayApp.controllers').controller('indexController', function($r
}); });
}; };
self.initAmazon = function() {
self.amazonEnabled = configService.getSync().amazon.enabled;
self.amazonTestnet = configService.getSync().amazon.testnet;
var network = self.amazonTestnet ? 'testnet' : 'livenet';
if (!self.amazonEnabled) return;
amazonService.setCredentials(network);
};
self.isInFocus = function(walletId) { self.isInFocus = function(walletId) {
var fc = profileService.focusedClient; var fc = profileService.focusedClient;
return fc && fc.credentials.walletId == walletId; return fc && fc.credentials.walletId == walletId;

View file

@ -1,53 +1,45 @@
'use strict'; 'use strict';
angular.module('copayApp.controllers').controller('amazonCardDetailsController', function($scope, $timeout, amazonService, ongoingProcess) { angular.module('copayApp.controllers').controller('amazonCardDetailsController', function($scope, $log, $timeout, bwcError, amazonService, lodash, ongoingProcess) {
$scope.cancelGiftCard = function() {
var dataSrc = {
creationRequestId: $scope.card.creationRequestId,
gcId: $scope.card.gcId,
bitpayInvoiceId: $scope.card.bitpayInvoiceId,
bitpayInvoiceUrl: $scope.card.bitpayInvoiceUrl,
date: $scope.card.date
};
ongoingProcess.set('Canceling gift card...', true);
amazonService.cancelGiftCard(dataSrc, function(err, data) {
ongoingProcess.set('Canceling gift card...', false);
if (err || data.status != 'SUCCESS') {
$scope.error = err || data.status;
return;
}
$scope.refreshGiftCard();
});
};
$scope.remove = function() { $scope.remove = function() {
amazonService.saveGiftCard($scope.card, {remove: true}, function(err) { amazonService.savePendingGiftCard($scope.card, {
remove: true
}, function(err) {
$scope.$emit('UpdateAmazonList'); $scope.$emit('UpdateAmazonList');
$scope.cancel(); $scope.cancel();
}); });
}; };
$scope.refreshGiftCard = function() { $scope.refreshGiftCard = function() {
var dataSrc = { amazonService.getPendingGiftCards(function(err, gcds) {
creationRequestId: $scope.card.creationRequestId,
amount: $scope.card.cardInfo.value.amount,
currencyCode: $scope.card.cardInfo.value.currencyCode,
bitpayInvoiceId: $scope.card.bitpayInvoiceId,
bitpayInvoiceUrl: $scope.card.bitpayInvoiceUrl,
date: $scope.card.date
};
ongoingProcess.set('Updating gift card...', true);
amazonService.createGiftCard(dataSrc, function(err, data) {
ongoingProcess.set('Updating gift card...', false);
if (err) { if (err) {
$scope.error = err; self.error = err;
return; return;
} }
$scope.$emit('UpdateAmazonList'); lodash.forEach(gcds, function(dataFromStorage) {
$scope.card = data; if (dataFromStorage.status == 'PENDING' && dataFromStorage.invoiceId == $scope.card.invoiceId) {
$timeout(function() { $log.debug("creating gift card");
$scope.$digest(); amazonService.createGiftCard(dataFromStorage, function(err, giftCard) {
if (err) {
self.error = bwcError.msg(err);
$log.debug(bwcError.msg(err));
return;
}
if (!lodash.isEmpty(giftCard)) {
var newData = {};
lodash.merge(newData, dataFromStorage, giftCard);
amazonService.savePendingGiftCard(newData, null, function(err) {
$log.debug("Saving new gift card");
$scope.card = newData;
$scope.$emit('UpdateAmazonList');
$timeout(function() {
$scope.$digest();
});
});
} else $log.debug("pending gift card not available yet");
});
}
}); });
}); });
}; };

View file

@ -3,35 +3,20 @@
angular.module('copayApp.services').factory('amazonService', function($http, $log, lodash, moment, storageService, configService, platformInfo) { angular.module('copayApp.services').factory('amazonService', function($http, $log, lodash, moment, storageService, configService, platformInfo) {
var root = {}; var root = {};
var credentials = {}; var credentials = {};
var DAILYLIMIT = 500;
root.setCredentials = function(network) { root.setCredentials = function(network) {
credentials.AMAZON_SANDBOX = network == 'testnet' ? true : false;
credentials.AMAZON_SERVICE_NAME = 'AGCODService';
if (network == 'testnet') { if (network == 'testnet') {
credentials.BITPAY_API_URL = window.amazon_sandbox_bitpay_api_url; credentials.BITPAY_API_URL = window.amazon_sandbox_bitpay_api_url;
credentials.BITPAY_API_TOKEN = window.amazon_sandbox_bitpay_api_token; credentials.BITPAY_API_TOKEN = window.amazon_sandbox_bitpay_api_token;
credentials.AMAZON_ACCESS_KEY = window.amazon_sandbox_access_key; } else {
credentials.AMAZON_SECRET_KEY = window.amazon_sandbox_secret_key;
credentials.AMAZON_PARTNER_ID = window.amazon_sandbox_partner_id;
credentials.AMAZON_REGION = window.amazon_sandbox_region;
credentials.AMAZON_ENDPOINT = window.amazon_sandbox_endpoint;
}
else {
credentials.BITPAY_API_URL = window.amazon_bitpay_api_url; credentials.BITPAY_API_URL = window.amazon_bitpay_api_url;
credentials.BITPAY_API_TOKEN = window.amazon_bitpay_api_token; credentials.BITPAY_API_TOKEN = window.amazon_bitpay_api_token;
credentials.AMAZON_ACCESS_KEY = window.amazon_access_key;
credentials.AMAZON_SECRET_KEY = window.amazon_secret_key;
credentials.AMAZON_PARTNER_ID = window.amazon_partner_id;
credentials.AMAZON_REGION = window.amazon_region;
credentials.AMAZON_ENDPOINT = window.amazon_endpoint;
}; };
}; };
var _getUuid = function(cb) { var _getUuid = function(cb) {
var isCordova = platformInfo.isCordova; var isCordova = platformInfo.isCordova;
if (isCordova) { if (isCordova) {
window.plugins.uniqueDeviceID.get(function(uuid) { window.plugins.uniqueDeviceID.get(function(uuid) {
return cb(uuid); return cb(uuid);
@ -44,154 +29,6 @@ angular.module('copayApp.services').factory('amazonService', function($http, $lo
} }
}; };
var _checkLimits = function(amount, cb) {
var network = configService.getSync().amazon.testnet ? 'testnet' : 'livenet';
var dateStamp = moment.utc().format('YYYY-MM-DD');
storageService.getAmazon(network, function(err, amazon) {
if (err) $log.error(err);
if (lodash.isEmpty(amazon)) return cb('CAN_NOT_GET_DATA_FROM_STORAGE');
if (lodash.isString(amazon)) {
amazon = JSON.parse(amazon);
}
if (amazon.date == dateStamp && (amazon.amount + amount) > DAILYLIMIT)
return cb('EXCEEDED_DAILY_LIMIT');
return cb();
});
};
root.healthCheckRequest = function() {
$http({
method: 'GET',
url: credentials.AMAZON_ENDPOINT + '/sping',
headers: {
'content-type': 'application/json'
}
}).then(function(data) {
$log.info('Amazon Health Check: SUCCESS');
}, function(data) {
$log.error('Amazon Health Check: ERROR ' + data.data.error);
});
};
root.initUuid = function() {
var network = configService.getSync().amazon.testnet ? 'testnet' : 'livenet';
var dateStamp = moment.utc().format('YYYY-MM-DD');
_getUuid(function(uuid) {
storageService.getAmazon(network, function(err, amazon) {
if (err) $log.error(err);
if (lodash.isEmpty(amazon))
amazon = {
uuid: uuid,
date: dateStamp,
amount: 0
};
if (lodash.isString(amazon)) {
amazon = JSON.parse(amazon);
}
amazon.uuid = uuid;
if (amazon.date != dateStamp) {
amazon.date = dateStamp;
amazon.amount = 0;
}
amazon = JSON.stringify(amazon);
storageService.setAmazon(network, amazon, function(err) {
if (err) $log.error(err);
});
});
});
};
root.setAmountByDay = function(amount) {
var network = configService.getSync().amazon.testnet ? 'testnet' : 'livenet';
var dateStamp = moment.utc().format('YYYY-MM-DD');
storageService.getAmazon(network, function(err, amazon) {
if (err) $log.error(err);
if (lodash.isString(amazon)) {
amazon = JSON.parse(amazon);
}
if (amazon.date == dateStamp) {
amazon.amount = amazon.amount + amount;
} else {
amazon.date = dateStamp;
amazon.amount = amount;
}
amazon = JSON.stringify(amazon);
storageService.setAmazon(network, amazon, function(err) {
if (err) $log.error(err);
});
});
};
var _getSignatureKey = function() {
var key = credentials.AMAZON_SECRET_KEY;
var dateStamp = moment.utc().format('YYYYMMDD');
var regionName = credentials.AMAZON_REGION;
var serviceName = credentials.AMAZON_SERVICE_NAME;
var kDate= CryptoJS.HmacSHA256(dateStamp, "AWS4" + key, { asBytes: true});
var kRegion= CryptoJS.HmacSHA256(regionName, kDate, { asBytes: true });
var kService=CryptoJS.HmacSHA256(serviceName, kRegion, { asBytes: true });
var kSigning= CryptoJS.HmacSHA256("aws4_request", kService, { asBytes: true });
return kSigning;
}
var _getHeaders = function(data, method, endpoint, amz_target) {
var content_type = 'application/json';
var accept = 'application/json';
var amz_date = moment.utc().format('YYYYMMDD[T]HHmmss[Z]');
var date_stamp = moment.utc().format('YYYYMMDD');
var canonical_querystring = '';
/************* TASK 1: CREATE A CANONICAL REQUEST *************/
var canonical_headers =
'accept:' + accept + '\n' +
'content-type:' + content_type + '\n' +
'host:' + credentials.AMAZON_ENDPOINT.replace('https://', '') + '\n' +
'x-amz-date:' + amz_date + '\n' +
'x-amz-target:' + amz_target + '\n';
var signed_headers = 'accept;content-type;host;x-amz-date;x-amz-target';
data = JSON.stringify(data);
var payload_hash = CryptoJS.SHA256(data).toString(CryptoJS.enc.Hex);
var canonical_request = method + '\n' + endpoint + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash;
/************* TASK 2: CREATE THE STRING TO SIGN *************/
var algorithm = 'AWS4-HMAC-SHA256';
var credential_scope = date_stamp + '/' + credentials.AMAZON_REGION + '/' + credentials.AMAZON_SERVICE_NAME + '/' + 'aws4_request';
var hashed_canonical_request = CryptoJS.SHA256(canonical_request).toString(CryptoJS.enc.Hex);
var string_to_sign = algorithm + '\n' + amz_date + '\n' + credential_scope + '\n' + hashed_canonical_request;
/************* TASK 3: CALCULATE THE SIGNATURE *************/
var signing_key = _getSignatureKey();
var signature = CryptoJS.HmacSHA256(string_to_sign, signing_key).toString(CryptoJS.enc.Hex)
var authorization_header = algorithm + ' ' + 'Credential=' + credentials.AMAZON_ACCESS_KEY + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature;
/************* TASK 4: ADD SIGNING INFORMATION TO THE REQUEST *************/
return {
'Content-Type': content_type,
'Accept': accept,
'X-Amz-Date': amz_date,
'X-Amz-Target': amz_target,
'Authorization': authorization_header
};
};
var _getBitPay = function(endpoint) { var _getBitPay = function(endpoint) {
return { return {
method: 'GET', method: 'GET',
@ -212,41 +49,9 @@ angular.module('copayApp.services').factory('amazonService', function($http, $lo
}, },
data: data data: data
}; };
};
root.createBitPayInvoice = function(data, cb) {
_getUuid(function(uuid) {
if (lodash.isEmpty(uuid)) return cb('CAN_NOT_GET_UUID');
var dataSrc = {
price: data.price,
currency: data.currency,
orderId: data.orderId,
posData: '{uuid:' + uuid + '}'
};
_checkLimits(data.price, function(err) {
if (err) return cb(err);
$http(_postBitPay('/invoices', dataSrc)).then(function(data) {
$log.info('BitPay Create Invoice: SUCCESS');
return cb(null, data.data);
}, function(data) {
$log.error('BitPay Create Invoice: ERROR ' + data.data.error);
return cb(data.data.error);
});
});
});
}; };
root.getBitPayInvoice = function(id, cb) { root.savePendingGiftCard = function(gc, opts, cb) {
$http(_getBitPay('/invoices/' + id)).then(function(data) {
$log.info('BitPay Get Invoice: SUCCESS');
return cb(null, data.data);
}, function(data) {
$log.error('BitPay Get Invoice: ERROR ' + data.data.error);
return cb(data.data.error);
});
};
root.saveGiftCard = function(gc, opts, cb) {
var network = configService.getSync().amazon.testnet ? 'testnet' : 'livenet'; var network = configService.getSync().amazon.testnet ? 'testnet' : 'livenet';
storageService.getAmazonGiftCards(network, function(err, oldGiftCards) { storageService.getAmazonGiftCards(network, function(err, oldGiftCards) {
if (lodash.isString(oldGiftCards)) { if (lodash.isString(oldGiftCards)) {
@ -256,12 +61,12 @@ angular.module('copayApp.services').factory('amazonService', function($http, $lo
gc = JSON.parse(gc); gc = JSON.parse(gc);
} }
var inv = oldGiftCards || {}; var inv = oldGiftCards || {};
inv[gc.gcId] = gc; inv[gc.invoiceId] = gc;
if (opts && (opts.error || opts.status)) { if (opts && (opts.error || opts.status)) {
inv[gc.gcId] = lodash.assign(inv[gc.gcId], opts); inv[gc.invoiceId] = lodash.assign(inv[gc.invoiceId], opts);
} }
if (opts && opts.remove) { if (opts && opts.remove) {
delete(inv[gc.gcId]); delete(inv[gc.invoiceId]);
} }
inv = JSON.stringify(inv); inv = JSON.stringify(inv);
@ -271,81 +76,64 @@ angular.module('copayApp.services').factory('amazonService', function($http, $lo
}); });
}; };
root.getGiftCards = function(cb) { root.getPendingGiftCards = function(cb) {
var network = configService.getSync().amazon.testnet ? 'testnet' : 'livenet'; var network = configService.getSync().amazon.testnet ? 'testnet' : 'livenet';
storageService.getAmazonGiftCards(network, function(err, giftCards) { storageService.getAmazonGiftCards(network, function(err, giftCards) {
var _gcds = giftCards ? JSON.parse(giftCards) : null; var _gcds = giftCards ? JSON.parse(giftCards) : null;
return cb(err, _gcds); return cb(err, _gcds);
}); });
}; };
root.createGiftCard = function(dataSrc, cb) { root.createBitPayInvoice = function(data, cb) {
var environment = credentials.AMAZON_SANDBOX ? 'T' : 'P'; // T: test - P: production _getUuid(function(uuid) {
var now = moment().unix(); if (lodash.isEmpty(uuid)) return cb('CAN_NOT_GET_UUID');
var requestId = dataSrc.creationRequestId || credentials.AMAZON_PARTNER_ID + environment + now; var dataSrc = {
currency: data.currency,
var data = { amount: data.amount,
'creationRequestId': requestId, clientId: uuid
'partnerId': credentials.AMAZON_PARTNER_ID, };
'value': {
'currencyCode': dataSrc.currencyCode,
'amount': dataSrc.amount
}
};
var method = 'POST'; $http(_postBitPay('/amazon-gift/pay', dataSrc)).then(function(data) {
var endpoint = '/CreateGiftCard'; $log.info('BitPay Create Invoice: SUCCESS');
var amz_target = 'com.amazonaws.agcod.AGCODService.CreateGiftCard'; return cb(null, data.data);
}, function(data) {
var headers = _getHeaders(data, method, endpoint, amz_target); $log.error('BitPay Create Invoice: ERROR ' + data.data.message);
return cb(data.data);
$http({
'method': method,
'url': credentials.AMAZON_ENDPOINT + endpoint,
'data': JSON.stringify(data),
'headers': headers
}).then(function(data) {
$log.info('Amazon.com Gift Card Create/Update: SUCCESS');
var newData = data.data;
newData['bitpayInvoiceId'] = dataSrc.bitpayInvoiceId;
newData['bitpayInvoiceUrl'] = dataSrc.bitpayInvoiceUrl;
newData['date'] = dataSrc.date || now;
root.saveGiftCard(newData, null, function(err) {
return cb(null, newData);
}); });
}, function(data) {
$log.error('Amazon.com Gift Card Create/Update: ERROR ' + data.statusText);
return cb(data.statusText);
}); });
}; };
root.cancelGiftCard = function(dataSrc, cb) { root.getBitPayInvoice = function(id, cb) {
var data = { $http(_getBitPay('/invoices/' + id)).then(function(data) {
'creationRequestId': dataSrc.creationRequestId, $log.info('BitPay Get Invoice: SUCCESS');
'partnerId': credentials.AMAZON_PARTNER_ID, return cb(null, data.data.data);
'gcId': dataSrc.gcId,
};
var method = 'POST';
var endpoint = '/CancelGiftCard';
var amz_target = 'com.amazonaws.agcod.AGCODService.CancelGiftCard';
var headers = _getHeaders(data, method, endpoint, amz_target);
$http({
'method': method,
'url': credentials.AMAZON_ENDPOINT + endpoint,
'data': JSON.stringify(data),
'headers': headers
}).then(function(data) {
$log.info('Amazon.com Gift Card Cancel: SUCCESS');
return cb(null, data.data);
}, function(data) { }, function(data) {
$log.error('Amazon.com Gift Card Cancel: ERROR ' + data.statusText); $log.error('BitPay Get Invoice: ERROR ' + data.data.error);
return cb(data.statusText); return cb(data.data.error);
}); });
}; };
root.createGiftCard = function(dataInvoice, cb) {
_getUuid(function(uuid) {
var dataSrc = {
"clientId": uuid,
"invoiceId": dataInvoice.invoiceId,
"accessKey": dataInvoice.accessKey
};
$http(_postBitPay('/amazon-gift/redeem', dataSrc)).then(function(data) {
var status = data.data.status == ('new' || 'paid') ? 'PENDING' : data.data.status;
data.data.status = status;
data.data.clientId = uuid;
$log.info('Amazon.com Gift Card Create/Update: ' + status);
return cb(null, data.data);
}, function(data) {
$log.error('Amazon.com Gift Card Create/Update: ' + data.data.message);
return cb(data.data);
});
})
};
return root; return root;
}); });

View file

@ -317,7 +317,7 @@ angular.module('copayApp.services')
}); });
}); });
}; };
root.setAmazonGiftCards = function(network, gcs, cb) { root.setAmazonGiftCards = function(network, gcs, cb) {
storage.set('amazonGiftCards-' + network, gcs, cb); storage.set('amazonGiftCards-' + network, gcs, cb);
}; };
@ -330,17 +330,5 @@ angular.module('copayApp.services')
storage.remove('amazonGiftCards-' + network, cb); storage.remove('amazonGiftCards-' + network, cb);
}; };
root.setAmazon = function(network, data, cb) {
storage.set('amazon-' + network, data, cb);
};
root.getAmazon = function(network, cb) {
storage.get('amazon-' + network, cb);
};
root.removeAmazon = function(network, cb) {
storage.remove('amazon-' + network, cb);
};
return root; return root;
}); });

View file

@ -729,6 +729,10 @@ ul.manage li {
padding: 20px; padding: 20px;
} }
.p15t {
padding-top: 15px;
}
.p20t { .p20t {
padding-top: 20px; padding-top: 20px;
} }