aboutsummaryrefslogtreecommitdiff
path: root/src/webex/pages
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2018-01-19 01:27:27 +0100
committerFlorian Dold <florian.dold@gmail.com>2018-01-19 01:27:27 +0100
commit1671d9a508b803af31762bcd9508e70eb40e7b48 (patch)
tree24d79103d0661c9edafd1d6371692b726b2f0ef3 /src/webex/pages
parent2f68e9e50e83c55ca46e9d4d72956d6525d0fa8c (diff)
downloadwallet-core-1671d9a508b803af31762bcd9508e70eb40e7b48.tar.xz
refactor tipping, adjust to new redirect-based API
Diffstat (limited to 'src/webex/pages')
-rw-r--r--src/webex/pages/confirm-contract.tsx73
-rw-r--r--src/webex/pages/tip.tsx16
2 files changed, 57 insertions, 32 deletions
diff --git a/src/webex/pages/confirm-contract.tsx b/src/webex/pages/confirm-contract.tsx
index cd58d712a..2ec131052 100644
--- a/src/webex/pages/confirm-contract.tsx
+++ b/src/webex/pages/confirm-contract.tsx
@@ -122,6 +122,7 @@ interface ContractPromptState {
*/
holdCheck: boolean;
payStatus?: CheckPayResult;
+ replaying: boolean;
}
class ContractPrompt extends React.Component<ContractPromptProps, ContractPromptState> {
@@ -135,6 +136,7 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
payDisabled: true,
proposal: null,
proposalId: props.proposalId,
+ replaying: false,
};
}
@@ -150,13 +152,23 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
if (this.props.resourceUrl) {
const p = await wxApi.queryPaymentByFulfillmentUrl(this.props.resourceUrl);
console.log("query for resource url", this.props.resourceUrl, "result", p);
- if (p.found && (p.lastSessionSig === undefined || p.lastSessionSig === this.props.sessionId)) {
- const nextUrl = new URI(p.contractTerms.fulfillment_url);
- nextUrl.addSearch("order_id", p.contractTerms.order_id);
- if (p.lastSessionSig) {
- nextUrl.addSearch("session_sig", p.lastSessionSig);
+ if (p) {
+ if (p.lastSessionSig === undefined || p.lastSessionSig === this.props.sessionId) {
+ const nextUrl = new URI(p.contractTerms.fulfillment_url);
+ nextUrl.addSearch("order_id", p.contractTerms.order_id);
+ if (p.lastSessionSig) {
+ nextUrl.addSearch("session_sig", p.lastSessionSig);
+ }
+ location.replace(nextUrl.href());
+ return;
+ } else {
+ // We're in a new session
+ this.setState({ replaying: true });
+ const payResult = await wxApi.submitPay(p.contractTermsHash, this.props.sessionId);
+ console.log("payResult", payResult);
+ location.replace(payResult.nextUrl);
+ return;
}
- location.href = nextUrl.href();
}
}
let proposalId = this.props.proposalId;
@@ -230,6 +242,9 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
if (this.props.contractUrl === undefined && this.props.proposalId === undefined) {
return <span>Error: either contractUrl or proposalId must be given</span>;
}
+ if (this.state.replaying) {
+ return <span>Re-submitting existing payment</span>;
+ }
if (this.state.proposalId === undefined) {
return <span>Downloading contract terms</span>;
}
@@ -245,26 +260,40 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
}
const amount = <strong>{renderAmount(c.amount)}</strong>;
console.log("payStatus", this.state.payStatus);
+
+ let products = null;
+ if (c.products.length) {
+ products = (
+ <>
+ <span>The following items are included:</span>
+ <ul>
+ {c.products.map(
+ (p: any, i: number) => (<li key={i}>{p.description}: {renderAmount(p.price)}</li>))
+ }
+ </ul>
+ </>
+ );
+ }
return (
- <div>
+ <>
<div>
<i18n.Translate wrap="p">
The merchant <span>{merchantName}</span> {" "}
offers you to purchase:
</i18n.Translate>
- <ul>
- {c.products.map(
- (p: any, i: number) => (<li key={i}>{p.description}: {renderAmount(p.price)}</li>))
- }
- </ul>
- {(this.state.payStatus && this.state.payStatus.coinSelection)
- ? <p>
- The total price is <span>{amount}</span>{" "}
- (plus <span>{renderAmount(this.state.payStatus.coinSelection.totalFees)}</span> fees).
- </p>
- :
- <p>The total price is <span>{amount}</span>.</p>
- }
+ <div style={{"text-align": "center"}}>
+ <strong>{c.summary}</strong>
+ </div>
+ <strong></strong>
+ {products}
+ {(this.state.payStatus && this.state.payStatus.coinSelection)
+ ? <p>
+ The total price is <span>{amount}</span>{" "}
+ (plus <span>{renderAmount(this.state.payStatus.coinSelection.totalFees)}</span> fees).
+ </p>
+ :
+ <p>The total price is <span>{amount}</span>.</p>
+ }
</div>
<button className="pure-button button-success"
disabled={this.state.payDisabled}
@@ -280,7 +309,7 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
{(this.state.error ? <p className="errorbox">{this.state.error}</p> : <p />)}
</div>
<Details exchanges={this.state.exchanges} contractTerms={c} collapsed={!this.state.error}/>
- </div>
+ </>
);
}
}
@@ -296,10 +325,8 @@ document.addEventListener("DOMContentLoaded", () => {
} catch {
// ignore error
}
-
const sessionId = query.sessionId;
const contractUrl = query.contractUrl;
-
const resourceUrl = query.resourceUrl;
ReactDOM.render(
diff --git a/src/webex/pages/tip.tsx b/src/webex/pages/tip.tsx
index 7f96401c5..578ae6aa4 100644
--- a/src/webex/pages/tip.tsx
+++ b/src/webex/pages/tip.tsx
@@ -39,11 +39,11 @@ import {
} from "../renderHtml";
import * as Amounts from "../../amounts";
+import { TipToken } from "../../talerTypes";
import { TipStatus } from "../../walletTypes";
interface TipDisplayProps {
- merchantDomain: string;
- tipId: string;
+ tipToken: TipToken;
}
interface TipDisplayState {
@@ -58,7 +58,7 @@ class TipDisplay extends React.Component<TipDisplayProps, TipDisplayState> {
}
async update() {
- const tipStatus = await getTipStatus(this.props.merchantDomain, this.props.tipId);
+ const tipStatus = await getTipStatus(this.props.tipToken);
this.setState({ tipStatus });
}
@@ -96,7 +96,7 @@ class TipDisplay extends React.Component<TipDisplayProps, TipDisplayState> {
accept() {
this.setState({ working: true});
- acceptTip(this.props.merchantDomain, this.props.tipId);
+ acceptTip(this.props.tipToken);
}
renderButtons() {
@@ -126,7 +126,7 @@ class TipDisplay extends React.Component<TipDisplayProps, TipDisplayState> {
<div>
<h2>Tip Received!</h2>
<p>You received a tip of <strong>{renderAmount(ts.tip.amount)}</strong> from <span> </span>
- <strong>{this.props.merchantDomain}</strong>.</p>
+ <strong>{ts.tip.merchantDomain}</strong>.</p>
{ts.tip.accepted
? <p>You've accepted this tip! <a href={ts.tip.nextUrl}>Go back to merchant</a></p>
: this.renderButtons()
@@ -142,11 +142,9 @@ async function main() {
const url = new URI(document.location.href);
const query: any = URI.parseQuery(url.query());
- const merchantDomain = query.merchant_domain;
- const tipId = query.tip_id;
- const props: TipDisplayProps = { tipId, merchantDomain };
+ const tipToken = TipToken.checked(JSON.parse(query.tip_token));
- ReactDOM.render(<TipDisplay {...props} />,
+ ReactDOM.render(<TipDisplay tipToken={tipToken} />,
document.getElementById("container")!);
} catch (e) {