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,21 +75,29 @@ document.addEventListener('taler-execute-payment', function (e) {
switch (r.status) {
case 200:
detail.success = true;
// Not supported by some browsers ...
detail.fulfillmentUrl = r.responseURL;
break;
case 301:
detail.success = true;
console.log("Headers:", r.getAllResponseHeaders());
detail.fulfillmentUrl = r.getResponseHeader('Location');
var respJson = JSON.parse(r.responseText);
console.log("respJson:", JSON.stringify(respJson));
if (!respJson) {
console.log("Invalid JSON in response from $pay_url");
detail.success = false;
break;
}
if (!respJson.fulfillment_url) {
console.log("Missing 'fulfillment_url' in response from $pay_url");
detail.success = false;
break;
}
detail.fulfillmentUrl = respJson.fulfillment_url;
break;
default:
console.log("Unexpected status code for $pay_url:", r.status);
detail.success = false;
break;
}
detail.status = r.status;
detail.responseText = r.responseText;
document.dispatchEvent(new CustomEvent("taler-payment-result", { detail: detail }));
detail.fulfillmentUrl =
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.addEventListener("taler-contract", function(e: CustomEvent) {
// XXX: the merchant should just give us the parsed data ...
let offer = JSON.parse(e.detail);
@ -84,21 +85,29 @@ document.addEventListener('taler-execute-payment', function(e: CustomEvent) {
switch (r.status) {
case 200:
detail.success = true;
// Not supported by some browsers ...
detail.fulfillmentUrl = (<any>r).responseURL;
break;
case 301:
detail.success = true;
console.log("Headers:", r.getAllResponseHeaders());
detail.fulfillmentUrl = r.getResponseHeader('Location');
let respJson = JSON.parse(r.responseText);
console.log("respJson:", JSON.stringify(respJson));
if (!respJson) {
console.log("Invalid JSON in response from $pay_url");
detail.success = false;
break;
}
if (!respJson.fulfillment_url) {
console.log("Missing 'fulfillment_url' in response from $pay_url");
detail.success = false;
break;
}
detail.fulfillmentUrl = respJson.fulfillment_url;
break;
default:
console.log("Unexpected status code for $pay_url:", r.status);
detail.success = false;
break;
}
detail.status = r.status;
detail.responseText = r.responseText;
detail.fulfillmentUrl =
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> {
let reservePriv = EddsaPrivateKey.create();
let reservePub = reservePriv.getPublicKey();
@ -500,19 +523,13 @@ export class Wallet {
.finish()
.then(() => {
// Do this in the background
this.updateMintFromUrl(reserveRecord.mint_base_url)
.then((mint) =>
this.updateReserve(reservePub, mint)
.then((reserve) => this.depleteReserve(reserve,
mint)))
.catch((e) => {
console.error("Failed to deplete reserve", e.stack);
});
this.initReserve(reserveRecord);
return resp;
});
});
}
withdrawPrepare(denom: Denomination,
reserve: Reserve): Promise<PreCoin> {
let reservePriv = new EddsaPrivateKey();
@ -616,6 +633,7 @@ export class Wallet {
.then(doBadge.bind(this));
}
storeCoin(coin: Coin): Promise<void> {
let historyEntry = {
type: "withdraw",
@ -644,7 +662,7 @@ export class Wallet {
/**
* 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 remaining = new Amount(reserve.current_amount);
denoms.sort(rankDenom);
@ -667,31 +685,34 @@ export class Wallet {
}
}
// Do the request one by one.
let next = () => {
if (workList.length == 0) {
return;
}
let d = workList.pop();
this.withdraw(d, reserve)
.then(() => next())
.catch((e) => {
console.log("Failed to withdraw coin", e.stack);
});
};
return new Promise<void>((resolve, reject) => {
// Do the request one by one.
let next = () => {
if (workList.length == 0) {
resolve();
}
let d = workList.pop();
this.withdraw(d, reserve)
.then(() => next())
.catch((e) => {
console.log("Failed to withdraw coin", e.stack);
reject();
});
};
// Asynchronous recursion
next();
// Asynchronous recursion
next();
});
}
updateReserve(reservePub: EddsaPublicKey,
updateReserve(reservePub: string,
mint): Promise<Reserve> {
let reservePubStr = reservePub.toCrock();
return Query(this.db)
.get("reserves", reservePubStr)
.get("reserves", reservePub)
.then((reserve) => {
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 => {
if (resp.status != 200) {
throw Error();

View File

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

View File

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