Real creation of gift card
This commit is contained in:
parent
05e57983c6
commit
6b2fbeae01
7 changed files with 164 additions and 46 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -7,6 +7,10 @@ src/js/translations.js
|
||||||
coinbase.json
|
coinbase.json
|
||||||
src/js/coinbase.js
|
src/js/coinbase.js
|
||||||
|
|
||||||
|
# Amazon.com API credentials
|
||||||
|
amazon.json
|
||||||
|
src/js/amazon.js
|
||||||
|
|
||||||
# version
|
# version
|
||||||
src/js/version.js
|
src/js/version.js
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,9 @@ module.exports = function(grunt) {
|
||||||
coinbase: {
|
coinbase: {
|
||||||
command: 'node ./util/coinbase.js'
|
command: 'node ./util/coinbase.js'
|
||||||
},
|
},
|
||||||
|
amazon: {
|
||||||
|
command: 'node ./util/amazon.js'
|
||||||
|
},
|
||||||
clear: {
|
clear: {
|
||||||
command: 'rm -Rf bower_components node_modules'
|
command: 'rm -Rf bower_components node_modules'
|
||||||
},
|
},
|
||||||
|
|
@ -105,6 +108,7 @@ module.exports = function(grunt) {
|
||||||
'bower_components/angular-sanitize/angular-sanitize.js',
|
'bower_components/angular-sanitize/angular-sanitize.js',
|
||||||
'bower_components/ng-csv/build/ng-csv.js',
|
'bower_components/ng-csv/build/ng-csv.js',
|
||||||
'bower_components/angular-mocks/angular-mocks.js',
|
'bower_components/angular-mocks/angular-mocks.js',
|
||||||
|
'bower_components/crypto-js/crypto-js.js',
|
||||||
'angular-bitcore-wallet-client/angular-bitcore-wallet-client.js'
|
'angular-bitcore-wallet-client/angular-bitcore-wallet-client.js'
|
||||||
],
|
],
|
||||||
dest: 'public/lib/angular.js'
|
dest: 'public/lib/angular.js'
|
||||||
|
|
@ -121,6 +125,7 @@ module.exports = function(grunt) {
|
||||||
'src/js/translations.js',
|
'src/js/translations.js',
|
||||||
'src/js/version.js',
|
'src/js/version.js',
|
||||||
'src/js/coinbase.js',
|
'src/js/coinbase.js',
|
||||||
|
'src/js/amazon.js',
|
||||||
'src/js/init.js',
|
'src/js/init.js',
|
||||||
'src/js/trezor-url.js',
|
'src/js/trezor-url.js',
|
||||||
'bower_components/trezor-connect/login.js'
|
'bower_components/trezor-connect/login.js'
|
||||||
|
|
@ -266,7 +271,7 @@ module.exports = function(grunt) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
grunt.registerTask('default', ['nggettext_compile', 'exec:version', 'exec:coinbase', 'browserify', 'sass', 'concat', 'copy:icons', 'copy:ionic_fonts']);
|
grunt.registerTask('default', ['nggettext_compile', 'exec:version', 'exec:coinbase', 'exec:amazon', 'browserify', 'sass', 'concat', 'copy:icons', 'copy:ionic_fonts']);
|
||||||
grunt.registerTask('prod', ['default', 'uglify']);
|
grunt.registerTask('prod', ['default', 'uglify']);
|
||||||
grunt.registerTask('translate', ['nggettext_extract']);
|
grunt.registerTask('translate', ['nggettext_extract']);
|
||||||
grunt.registerTask('test', ['karma:unit']);
|
grunt.registerTask('test', ['karma:unit']);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
<section class="middle tab-bar-section">
|
<section class="middle tab-bar-section">
|
||||||
<h1 class="title ellipsis">
|
<h1 class="title ellipsis">
|
||||||
Amazon Gift Card
|
Amazon.com Gift Card
|
||||||
</h1>
|
</h1>
|
||||||
</section>
|
</section>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
||||||
|
|
@ -105,9 +105,10 @@ angular.module('copayApp.controllers').controller('buyAmazonController',
|
||||||
this.createTx = function() {
|
this.createTx = function() {
|
||||||
self.error = null;
|
self.error = null;
|
||||||
|
|
||||||
|
var currency_code = configService.getSync().amazon.testnet ? window.amazon_sandbox_currency_code : window.amazon_currency_code;
|
||||||
var dataSrc = {
|
var dataSrc = {
|
||||||
price: $scope.fiat,
|
price: $scope.fiat,
|
||||||
currency: 'USD'
|
currency: currency_code
|
||||||
};
|
};
|
||||||
var outputs = [];
|
var outputs = [];
|
||||||
var config = configService.getSync();
|
var config = configService.getSync();
|
||||||
|
|
@ -129,7 +130,7 @@ angular.module('copayApp.controllers').controller('buyAmazonController',
|
||||||
|
|
||||||
address = data.data.bitcoinAddress;
|
address = data.data.bitcoinAddress;
|
||||||
amount = parseInt((data.data.btcPrice * 100000000).toFixed(0));
|
amount = parseInt((data.data.btcPrice * 100000000).toFixed(0));
|
||||||
comment = 'Buy Amazon Gift Card';
|
comment = 'Amazon.com Gift Card';
|
||||||
|
|
||||||
outputs.push({
|
outputs.push({
|
||||||
'toAddress': address,
|
'toAddress': address,
|
||||||
|
|
@ -172,8 +173,8 @@ angular.module('copayApp.controllers').controller('buyAmazonController',
|
||||||
bitpayInvoiceId: data.data.id,
|
bitpayInvoiceId: data.data.id,
|
||||||
bitpayInvoiceUrl: data.data.url
|
bitpayInvoiceUrl: data.data.url
|
||||||
};
|
};
|
||||||
self.loading = 'Buying gift card...';
|
self.loading = 'Creating gift card...';
|
||||||
amazonService.buyGiftCard(gift, function(err, giftCard) {
|
amazonService.createGiftCard(gift, function(err, giftCard) {
|
||||||
self.loading = null;
|
self.loading = null;
|
||||||
if (err) {
|
if (err) {
|
||||||
self.error = err;
|
self.error = err;
|
||||||
|
|
|
||||||
|
|
@ -1,46 +1,52 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('copayApp.services').factory('amazonService', function($http, $log, isCordova, lodash, storageService, configService) {
|
angular.module('copayApp.services').factory('amazonService', function($http, $log, isCordova, lodash, moment, storageService, configService) {
|
||||||
var root = {};
|
var root = {};
|
||||||
var credentials = {};
|
var credentials = {};
|
||||||
|
|
||||||
var fakeData = {
|
|
||||||
"cardInfo": {
|
|
||||||
"cardNumber":null,
|
|
||||||
"cardStatus":"RefundedToPurchaser",
|
|
||||||
"expirationDate":null,
|
|
||||||
"value":{
|
|
||||||
"amount":1.0,
|
|
||||||
"currencyCode":"USD"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"creationRequestId":"AwssbTSpecTest001",
|
|
||||||
"gcClaimCode":"Z7NV-LBBG39-75MU",
|
|
||||||
"gcExpirationDate":null,
|
|
||||||
"gcId":"A2GCN9BRX5QS76",
|
|
||||||
"status":"SUCCESS",
|
|
||||||
"bitpayInvoiceId":"NJtevvEponHbQVmYoL7FYp",
|
|
||||||
"bitpayInvoiceUrl":"http://test.bitpay.com/invoice?id=XwrLryQEypTKg4nq37t3bN"
|
|
||||||
};
|
|
||||||
|
|
||||||
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 = 'https://test.bitpay.com';
|
credentials.BITPAY_API_URL = window.amazon_sandbox_bitpay_api_url;
|
||||||
credentials.BITPAY_API_TOKEN = 'GDtYwBqbMZvjz5JrYZ1d2ba96StV92U4Yg4AGhT3C4He';
|
credentials.BITPAY_API_TOKEN = window.amazon_sandbox_bitpay_api_token;
|
||||||
credentials.AMAZON_HOST = 'https://agcod-v2-gamma.amazon.com';
|
credentials.AMAZON_ACCESS_KEY = window.amazon_sandbox_access_key;
|
||||||
|
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 {
|
else {
|
||||||
credentials.BITPAY_API = 'https://bitpay.com';
|
credentials.BITPAY_API_URL = window.amazon_bitpay_api_url;
|
||||||
credentials.BITPAY_API_TOKEN = window.bitpay_token;
|
credentials.BITPAY_API_TOKEN = window.amazon_bitpay_api_token;
|
||||||
credentials.AMAZON_HOST = 'https://agcod-v2.amazon.com';
|
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 _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 _getBitPay = function(endpoint) {
|
var _getBitPay = function(endpoint) {
|
||||||
return {
|
return {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: credentials.BITPAY_API + endpoint,
|
url: credentials.BITPAY_API_URL + endpoint,
|
||||||
headers: {
|
headers: {
|
||||||
'content-type': 'application/json'
|
'content-type': 'application/json'
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +57,7 @@ angular.module('copayApp.services').factory('amazonService', function($http, $lo
|
||||||
data.token = credentials.BITPAY_API_TOKEN;
|
data.token = credentials.BITPAY_API_TOKEN;
|
||||||
return {
|
return {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: credentials.BITPAY_API + endpoint,
|
url: credentials.BITPAY_API_URL + endpoint,
|
||||||
headers: {
|
headers: {
|
||||||
'content-type': 'application/json'
|
'content-type': 'application/json'
|
||||||
},
|
},
|
||||||
|
|
@ -116,17 +122,81 @@ angular.module('copayApp.services').factory('amazonService', function($http, $lo
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
root.buyGiftCard = function(gift, cb) {
|
root.createGiftCard = function(dataSrc, cb) {
|
||||||
var newId = Math.floor(Date.now() / 1000);
|
var sandbox = credentials.AMAZON_SANDBOX ? 'T' : 'P'; // T: test - P: production
|
||||||
var saveData = fakeData;
|
var now = moment().unix();
|
||||||
saveData.gcId = saveData.gcId + '' + newId;
|
var requestId = credentials.AMAZON_PARTNER_ID + sandbox + now;
|
||||||
saveData.cardInfo.value.amount = gift.amount;
|
|
||||||
saveData.cardInfo.value.currencyCode = gift.currencyCode;
|
var data = {
|
||||||
saveData['bitpayInvoiceId'] = gift.bitpayInvoiceId;
|
'creationRequestId': requestId,
|
||||||
saveData['bitpayInvoiceUrl'] = gift.bitpayInvoiceUrl;
|
'partnerId': credentials.AMAZON_PARTNER_ID,
|
||||||
saveData['date'] = newId;
|
'value': {
|
||||||
root.saveGiftCard(saveData, null, function(err) {
|
'currencyCode': dataSrc.currencyCode,
|
||||||
return cb(null, fakeData);
|
'amount': dataSrc.amount
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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 amz_target = 'com.amazonaws.agcod.AGCODService.CreateGiftCard';
|
||||||
|
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 = 'POST' + '\n' + '/CreateGiftCard' + '\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 *************/
|
||||||
|
|
||||||
|
var headers = {
|
||||||
|
'Content-Type': content_type,
|
||||||
|
'Accept': accept,
|
||||||
|
'X-Amz-Date': amz_date,
|
||||||
|
'X-Amz-Target': amz_target,
|
||||||
|
'Authorization': authorization_header
|
||||||
|
};
|
||||||
|
|
||||||
|
$http({
|
||||||
|
'method': 'POST',
|
||||||
|
'url': credentials.AMAZON_ENDPOINT + '/CreateGiftCard',
|
||||||
|
'data': data,
|
||||||
|
'headers': headers
|
||||||
|
}).then(function(data) {
|
||||||
|
$log.info('Amazon Create Gift Card: SUCCESS');
|
||||||
|
var newData = data.data;
|
||||||
|
newData['bitpayInvoiceId'] = dataSrc.bitpayInvoiceId;
|
||||||
|
newData['bitpayInvoiceUrl'] = dataSrc.bitpayInvoiceUrl;
|
||||||
|
newData['date'] = now;
|
||||||
|
root.saveGiftCard(newData, null, function(err) {
|
||||||
|
return cb(null, newData);
|
||||||
|
});
|
||||||
|
}, function(data) {
|
||||||
|
$log.error('Amazon Create Gift Card: ERROR ' + data.statusText);
|
||||||
|
return cb(data.statusText);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -536,6 +536,10 @@ ul.manage li {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.size-28 {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
.size-36 {
|
.size-36 {
|
||||||
font-size: 36px;
|
font-size: 36px;
|
||||||
}
|
}
|
||||||
|
|
@ -1655,7 +1659,7 @@ a.missing-copayers {
|
||||||
.sidebar {
|
.sidebar {
|
||||||
background: #2C3E50;
|
background: #2C3E50;
|
||||||
.icon {
|
.icon {
|
||||||
width: 39px;
|
width: 35px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
float: left;
|
float: left;
|
||||||
|
|
|
||||||
34
util/amazon.js
Executable file
34
util/amazon.js
Executable file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var fs = require('fs');
|
||||||
|
var file;
|
||||||
|
|
||||||
|
try {
|
||||||
|
file = fs.readFileSync('./amazon.json', 'utf8');
|
||||||
|
} catch(err) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var json = JSON.parse(file);
|
||||||
|
console.log('Amazon Partner ID: ' + json.production.partner_id);
|
||||||
|
|
||||||
|
var content = 'window.amazon_sandbox_access_key="' + json.sandbox.access_key + '";';
|
||||||
|
content = content + '\nwindow.amazon_sandbox_secret_key="' + json.sandbox.secret_key + '";';
|
||||||
|
content = content + '\nwindow.amazon_sandbox_partner_id="' + json.sandbox.partner_id + '";';
|
||||||
|
content = content + '\nwindow.amazon_sandbox_currency_code="' + json.sandbox.currency_code + '";';
|
||||||
|
content = content + '\nwindow.amazon_sandbox_region="' + json.sandbox.region + '";';
|
||||||
|
content = content + '\nwindow.amazon_sandbox_endpoint="' + json.sandbox.endpoint + '";';
|
||||||
|
content = content + '\nwindow.amazon_sandbox_bitpay_api_token="' + json.sandbox.bitpay_api_token + '";';
|
||||||
|
content = content + '\nwindow.amazon_sandbox_bitpay_api_url="' + json.sandbox.bitpay_api_url + '";';
|
||||||
|
content = content + '\nwindow.amazon_access_key="' + json.production.access_key + '";';
|
||||||
|
content = content + '\nwindow.amazon_secret_key="' + json.production.secret_key + '";';
|
||||||
|
content = content + '\nwindow.amazon_partner_id="' + json.production.partner_id + '";';
|
||||||
|
content = content + '\nwindow.amazon_currency_code="' + json.production.currency_code + '";';
|
||||||
|
content = content + '\nwindow.amazon_region="' + json.production.region + '";';
|
||||||
|
content = content + '\nwindow.amazon_endpoint="' + json.production.endpoint + '";';
|
||||||
|
content = content + '\nwindow.amazon_bitpay_api_token="' + json.production.bitpay_api_token + '";';
|
||||||
|
content = content + '\nwindow.amazon_bitpay_api_url="' + json.production.bitpay_api_url + '";';
|
||||||
|
fs.writeFileSync("./src/js/amazon.js", content);
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue