-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
Copy pathcheck-user-can-make-payment.html
174 lines (148 loc) · 5.67 KB
/
check-user-can-make-payment.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset="UTF-8">
<title>Check Whether User Can Make Payment Before All Prices Are Known</title>
<!--
If the checkout flow needs to know whether `PaymentRequest.canMakePayment()` will
return true even before all line items and their prices are known, then you can
instantiate PaymentRequest with dummy data and pre-query `.canMakePayment()`.
If you call `.canMakePayment()` multiple times, keep in mind that the first parameter
to the PaymentRequest constructor should contain the same method names and data.
-->
<meta name="viewport" content="width=device-width">
<style>
#success,
#legacy {
display: none;
}
</style>
</head>
<body>
<h1>Check Whether User Can Make Payment Before All Prices Are Known</h1>
<div id="intro">
<p>
If the checkout flow needs to know whether <code>PaymentRequest.canMakePayment()</code>
will return true even before all line items and their prices are known, then you can
instantiate PaymentRequest with dummy data and pre-query <code>.canMakePayment()</code>.
</p>
<p>
If you call <code>.canMakePayment()</code> multiple times, keep in mind that the first
parameter to the PaymentRequest constructor should contain the same method names and data.
</p>
<p>
Please note that no payments will be taken, this is just a front-end demo.
If you would like to try entering card details, you can use dummy data,
for example the card number <code>4111 1111 1111 1111</code>.
</p>
<button id="checkout-button">Checkout</button>
</div>
<div id="success">
<p>
Payment Request success. Demo complete. No payment has been taken.
</p>
</div>
<div id="legacy">
<p>
The Payment Request API is unsupported or was cancelled or failed,
so here we can proceed with our legacy web form (not implemented for this demo).
</p>
</div>
<script type="text/javascript">
var checkoutButton = document.getElementById('checkout-button');
var introPanel = document.getElementById('intro');
var successPanel = document.getElementById('success');
var legacyPanel = document.getElementById('legacy');
// Feature detection
if (window.PaymentRequest) {
// Payment Request is supported in this browser, so we can proceed to use it
var shouldCallPaymentRequest = true;
// Make a dummy payment request to check if user can make payment
new PaymentRequest(buildSupportedPaymentMethodData(),
{total: {label: 'Stub', amount: {currency: 'USD', value: '0.01'}}})
.canMakePayment()
.then(function(result) {
shouldCallPaymentRequest = result;
}).catch(function(error) {
console.log(error);
// The user may have turned off query ability in their privacy settings.
// Let's use PaymentRequest by default & fallback to legacy web form checkout.
shouldCallPaymentRequest = true;
});
checkoutButton.addEventListener('click', function() {
callServerToRetrieveCheckoutDetails();
});
} else {
checkoutButton.addEventListener('click', function() {
// For demo purposes
introPanel.style.display = 'none';
legacyPanel.style.display = 'block';
});
}
function callServerToRetrieveCheckoutDetails() {
// Here we would call to the server with the chosen line items, to retrieve
// a `Checkout` object with all of the prices and shipping options.
// But for the purposes of this demo, we will skip that and proceed immediately.
onServerCheckoutDetailsRetrieved(buildShoppingCartDetails());
}
function onServerCheckoutDetailsRetrieved(checkoutObject) {
// The server has constructed the `Checkout` object. Now we know all of the prices
// and shipping options.
if (shouldCallPaymentRequest) {
var request = new PaymentRequest(buildSupportedPaymentMethodData(),
checkoutObject);
request.show().then(function(paymentResponse) {
// Here we would process the payment. For this demo, simulate immediate success:
paymentResponse.complete('success')
.then(function() {
// For demo purposes:
introPanel.style.display = 'none';
successPanel.style.display = 'block';
});
}).catch(function(error) {
// Handle cancelled/failed payment. Fall back to legacy form. For demo purposes:
introPanel.style.display = 'none';
legacyPanel.style.display = 'block';
});
} else {
// Fall back to legacy form. (We could redirect, but) for demo purposes:
introPanel.style.display = 'none';
legacyPanel.style.display = 'block';
}
}
function buildSupportedPaymentMethodData() {
// Example supported payment methods:
return [{
supportedMethods: 'basic-card',
data: {
supportedNetworks: ['visa', 'mastercard'],
supportedTypes: ['debit', 'credit']
}
}];
}
function buildShoppingCartDetails() {
// Hardcoded for demo purposes:
return {
id: 'order-123',
displayItems: [
{
label: 'Example item',
amount: {currency: 'USD', value: '1.00'}
}
],
total: {
label: 'Total',
amount: {currency: 'USD', value: '1.00'}
},
shippingOptions: [
{
id: 'example-shipping',
label: 'Example Shipping (2-3 Days)',
amount: {currency: 'USD', value: '0.50'}
}
]
};
}
</script>
</body>
</html>