parse json fulfillment url from payment

This commit is contained in:
Florian Dold 2016-01-24 19:57:09 +01:00
parent 53654b3622
commit 5f996fedbc
5 changed files with 101 additions and 46 deletions

View File

@ -75,20 +75,28 @@ document.addEventListener('taler-execute-payment', function (e) {
switch (r.status) { switch (r.status) {
case 200: case 200:
detail.success = true; detail.success = true;
// Not supported by some browsers ... var respJson = JSON.parse(r.responseText);
detail.fulfillmentUrl = r.responseURL; console.log("respJson:", JSON.stringify(respJson));
if (!respJson) {
console.log("Invalid JSON in response from $pay_url");
detail.success = false;
break; break;
case 301: }
detail.success = true; if (!respJson.fulfillment_url) {
console.log("Headers:", r.getAllResponseHeaders()); console.log("Missing 'fulfillment_url' in response from $pay_url");
detail.fulfillmentUrl = r.getResponseHeader('Location'); detail.success = false;
break;
}
detail.fulfillmentUrl = respJson.fulfillment_url;
break; break;
default: default:
console.log("Unexpected status code for $pay_url:", r.status);
detail.success = false; detail.success = false;
break; break;
} }
detail.status = r.status; detail.status = r.status;
detail.responseText = r.responseText; detail.responseText = r.responseText;
detail.fulfillmentUrl =
document.dispatchEvent(new CustomEvent("taler-payment-result", { detail: detail })); document.dispatchEvent(new CustomEvent("taler-payment-result", { detail: detail }));
}; };
}); });

View File

@ -49,6 +49,7 @@ document.addEventListener("taler-create-reserve", function(e: CustomEvent) {
document.location.href = uri.query(params).href(); document.location.href = uri.query(params).href();
}); });
document.addEventListener("taler-contract", function(e: CustomEvent) { document.addEventListener("taler-contract", function(e: CustomEvent) {
// XXX: the merchant should just give us the parsed data ... // XXX: the merchant should just give us the parsed data ...
let offer = JSON.parse(e.detail); let offer = JSON.parse(e.detail);
@ -84,20 +85,28 @@ document.addEventListener('taler-execute-payment', function(e: CustomEvent) {
switch (r.status) { switch (r.status) {
case 200: case 200:
detail.success = true; detail.success = true;
// Not supported by some browsers ... let respJson = JSON.parse(r.responseText);
detail.fulfillmentUrl = (<any>r).responseURL; console.log("respJson:", JSON.stringify(respJson));
if (!respJson) {
console.log("Invalid JSON in response from $pay_url");
detail.success = false;
break; break;
case 301: }
detail.success = true; if (!respJson.fulfillment_url) {
console.log("Headers:", r.getAllResponseHeaders()); console.log("Missing 'fulfillment_url' in response from $pay_url");
detail.fulfillmentUrl = r.getResponseHeader('Location'); detail.success = false;
break;
}
detail.fulfillmentUrl = respJson.fulfillment_url;
break; break;
default: default:
console.log("Unexpected status code for $pay_url:", r.status);
detail.success = false; detail.success = false;
break; break;
} }
detail.status = r.status; detail.status = r.status;
detail.responseText = r.responseText; detail.responseText = r.responseText;
detail.fulfillmentUrl =
document.dispatchEvent(new CustomEvent("taler-payment-result", {detail: detail})); document.dispatchEvent(new CustomEvent("taler-payment-result", {detail: detail}));
}; };
}); });

View File

@ -438,6 +438,29 @@ export class Wallet {
}); });
} }
initReserve(reserveRecord) {
this.updateMintFromUrl(reserveRecord.mint_base_url)
.then((mint) =>
this.updateReserve(reserveRecord.reserve_pub, mint)
.then((reserve) => this.depleteReserve(reserve,
mint)))
.then(() => {
let depleted = {
type: "depleted-reserve",
timestamp: (new Date).getTime(),
detail: {
reservePub: reserveRecord.reserve_pub,
}
};
return Query(this.db).put("history", depleted).finish();
})
.catch((e) => {
console.error("Failed to deplete reserve", e.stack);
});
}
confirmReserve(req: ConfirmReserveRequest): Promise<ConfirmReserveResponse> { confirmReserve(req: ConfirmReserveRequest): Promise<ConfirmReserveResponse> {
let reservePriv = EddsaPrivateKey.create(); let reservePriv = EddsaPrivateKey.create();
let reservePub = reservePriv.getPublicKey(); let reservePub = reservePriv.getPublicKey();
@ -500,19 +523,13 @@ export class Wallet {
.finish() .finish()
.then(() => { .then(() => {
// Do this in the background // Do this in the background
this.updateMintFromUrl(reserveRecord.mint_base_url) this.initReserve(reserveRecord);
.then((mint) =>
this.updateReserve(reservePub, mint)
.then((reserve) => this.depleteReserve(reserve,
mint)))
.catch((e) => {
console.error("Failed to deplete reserve", e.stack);
});
return resp; return resp;
}); });
}); });
} }
withdrawPrepare(denom: Denomination, withdrawPrepare(denom: Denomination,
reserve: Reserve): Promise<PreCoin> { reserve: Reserve): Promise<PreCoin> {
let reservePriv = new EddsaPrivateKey(); let reservePriv = new EddsaPrivateKey();
@ -616,6 +633,7 @@ export class Wallet {
.then(doBadge.bind(this)); .then(doBadge.bind(this));
} }
storeCoin(coin: Coin): Promise<void> { storeCoin(coin: Coin): Promise<void> {
let historyEntry = { let historyEntry = {
type: "withdraw", type: "withdraw",
@ -644,7 +662,7 @@ export class Wallet {
/** /**
* Withdraw coins from a reserve until it is empty. * Withdraw coins from a reserve until it is empty.
*/ */
depleteReserve(reserve, mint): void { depleteReserve(reserve, mint): Promise<void> {
let denoms = copy(mint.keys.denoms); let denoms = copy(mint.keys.denoms);
let remaining = new Amount(reserve.current_amount); let remaining = new Amount(reserve.current_amount);
denoms.sort(rankDenom); denoms.sort(rankDenom);
@ -667,31 +685,34 @@ export class Wallet {
} }
} }
return new Promise<void>((resolve, reject) => {
// Do the request one by one. // Do the request one by one.
let next = () => { let next = () => {
if (workList.length == 0) { if (workList.length == 0) {
return; resolve();
} }
let d = workList.pop(); let d = workList.pop();
this.withdraw(d, reserve) this.withdraw(d, reserve)
.then(() => next()) .then(() => next())
.catch((e) => { .catch((e) => {
console.log("Failed to withdraw coin", e.stack); console.log("Failed to withdraw coin", e.stack);
reject();
}); });
}; };
// Asynchronous recursion // Asynchronous recursion
next(); next();
});
} }
updateReserve(reservePub: EddsaPublicKey,
updateReserve(reservePub: string,
mint): Promise<Reserve> { mint): Promise<Reserve> {
let reservePubStr = reservePub.toCrock();
return Query(this.db) return Query(this.db)
.get("reserves", reservePubStr) .get("reserves", reservePub)
.then((reserve) => { .then((reserve) => {
let reqUrl = URI("reserve/status").absoluteTo(mint.baseUrl); let reqUrl = URI("reserve/status").absoluteTo(mint.baseUrl);
reqUrl.query({'reserve_pub': reservePubStr}); reqUrl.query({'reserve_pub': reservePub});
return this.http.get(reqUrl).then(resp => { return this.http.get(reqUrl).then(resp => {
if (resp.status != 200) { if (resp.status != 200) {
throw Error(); throw Error();

View File

@ -2,7 +2,9 @@ body {
min-height: 20em; min-height: 20em;
width: 30em; width: 30em;
margin: 0; margin: 0;
padding: 0 padding: 0;
max-height: 800px;
overflow: hidden;
} }
.nav { .nav {
@ -21,6 +23,16 @@ body {
font-weight: bold; font-weight: bold;
} }
.container {
overflow-y: scroll;
max-height: 400px;
}
.abbrev {
text-decoration-style: dotted;
}
#content { #content {
padding: 1em; padding: 1em;
} }

View File

@ -101,13 +101,18 @@ function formatAmount(amount) {
return `${v.toFixed(2)} ${amount.currency}`; return `${v.toFixed(2)} ${amount.currency}`;
} }
function abbrevKey(s: string) {
return m("span.abbrev", {title: s}, (s.slice(0,5) + ".."))
}
function formatHistoryItem(historyItem) { function formatHistoryItem(historyItem) {
const d = historyItem.detail; const d = historyItem.detail;
const t = historyItem.timestamp; const t = historyItem.timestamp;
switch (historyItem.type) { switch (historyItem.type) {
case "create-reserve": case "create-reserve":
return m("p", return m("p",
i18n`Created reserve of ${formatAmount(d.requestedAmount)} at ${formatTimestamp( i18n.parts`Created reserve (${abbrevKey(d.reservePub)}) of ${formatAmount(d.requestedAmount)} at ${formatTimestamp(
t)}`); t)}`);
case "withdraw": case "withdraw":
return m("p", return m("p",
@ -143,7 +148,7 @@ var WalletHistory = {
} }
let listing = _.map(history, formatHistoryItem); let listing = _.map(history, formatHistoryItem);
if (listing.length > 0) { if (listing.length > 0) {
return listing; return m("div.container", listing);
} }
return i18n`Your wallet has no events recorded.`; return i18n`Your wallet has no events recorded.`;
} }