|
27 | 27 |
|
28 | 28 | is: 'payment-request', |
29 | 29 |
|
| 30 | + /** |
| 31 | + * Fired when begin user interaction for the payment request. |
| 32 | + * |
| 33 | + * @event payment-response |
| 34 | + * @param {PaymentResponse} paymentResponse The payment information to process. |
| 35 | + */ |
| 36 | + |
| 37 | + /** |
| 38 | + * Fired when the payment request is aborted |
| 39 | + * |
| 40 | + * @event payment-aborted |
| 41 | + */ |
| 42 | + |
| 43 | + /** |
| 44 | + * Fired when payment request generate an error. |
| 45 | + * |
| 46 | + * @event error |
| 47 | + * @param {Error} error The request error. |
| 48 | + */ |
| 49 | + |
| 50 | + /** |
| 51 | + * Fired when browser not support payment request API. |
| 52 | + * |
| 53 | + * @event not-supported |
| 54 | + */ |
| 55 | + |
| 56 | + /** |
| 57 | + * Fired when PaymentRequest object can be used to make a payment. |
| 58 | + * |
| 59 | + * @event can-make-payment |
| 60 | + */ |
| 61 | + |
| 62 | + /** |
| 63 | + * Fired when PaymentRequest object cannot be used to make a payment. |
| 64 | + * |
| 65 | + * @event cannot-make-payment |
| 66 | + */ |
| 67 | + |
| 68 | + |
30 | 69 | properties: { |
31 | | - networks: Array, |
32 | | - types: Array, |
33 | | - currency: String, |
34 | | - value: Number, |
| 70 | + /** |
| 71 | + * This is a human-readable description of the total. |
| 72 | + * The user agent may display this to the user. |
| 73 | + */ |
35 | 74 | label: String, |
| 75 | + /** |
| 76 | + * A valid decimal monetary value containing a monetary amount of the total |
| 77 | + */ |
| 78 | + value: Number, |
| 79 | + /** |
| 80 | + * A string containing a currency identifier of the total. |
| 81 | + * The value of currency can be any string that is valid within |
| 82 | + * the currency system indicated by currencySystem. |
| 83 | + */ |
| 84 | + currency: String, |
| 85 | + /** |
| 86 | + * Contains line items for the payment request that the user agent may display. |
| 87 | + */ |
36 | 88 | items: { |
37 | 89 | type: Array, |
38 | 90 | value: function() { |
|
41 | 93 | readOnly: true, |
42 | 94 | observer: '_updateTotal' |
43 | 95 | }, |
| 96 | + /** |
| 97 | + * Contains the total amount of the payment request. |
| 98 | + */ |
44 | 99 | total: { |
45 | 100 | type: Object, |
46 | 101 | value: function() { |
47 | 102 | return {}; |
48 | 103 | }, |
49 | 104 | readOnly: true |
50 | 105 | }, |
| 106 | + /** |
| 107 | + * Card supported networks |
| 108 | + */ |
| 109 | + networks: Array, |
| 110 | + /** |
| 111 | + * Card supported types |
| 112 | + */ |
| 113 | + types: Array, |
| 114 | + /** |
| 115 | + * Is used to indicate a set of supported payment methods and |
| 116 | + * any associated payment method specific data for those methods. |
| 117 | + */ |
51 | 118 | methodData: { |
52 | 119 | type: Array, |
| 120 | + readOnly: true, |
53 | 121 | computed: '_computeMethodData(networks, types)' |
54 | 122 | }, |
| 123 | + /** |
| 124 | + * Provides information about the requested transaction. |
| 125 | + */ |
55 | 126 | details: { |
56 | 127 | type: Object, |
| 128 | + readOnly: true, |
57 | 129 | value: function() { |
58 | 130 | return {}; |
59 | 131 | }, |
| 132 | + }, |
| 133 | + |
| 134 | + lastCanMakePayment: { |
| 135 | + type: Boolean, |
| 136 | + readOnly: true |
| 137 | + }, |
| 138 | + lastPaymentRequest: { |
| 139 | + type: Object, |
| 140 | + readOnly: true |
| 141 | + }, |
| 142 | + lastPaymentResponse: { |
| 143 | + type: Object, |
| 144 | + readOnly: true |
| 145 | + }, |
| 146 | + lastError: { |
| 147 | + type: Object, |
| 148 | + readOnly: true |
60 | 149 | } |
61 | 150 | }, |
62 | 151 |
|
|
69 | 158 | this._updateTotal(); |
70 | 159 | var buyButton = Polymer.dom(this.$.buyButton).getDistributedNodes()[0]; |
71 | 160 | if ('PaymentRequest' in window) { |
72 | | - this.listen(buyButton, 'tap', 'processPurchase'); |
| 161 | + this.listen(buyButton, 'tap', 'show'); |
73 | 162 | } else { |
74 | 163 | buyButton.disabled = true; |
75 | 164 | this.dispatchEvent( |
|
84 | 173 | } |
85 | 174 | }, |
86 | 175 |
|
87 | | - processPurchase: function() { |
88 | | - this.paymentRequest().show() |
89 | | - .then(function(payment) { |
90 | | - this.fire('payment', payment); |
91 | | - }) |
92 | | - .catch(function(error) { |
93 | | - this.dispatchEvent( |
94 | | - new CustomEvent('error', error) |
95 | | - ); |
96 | | - }); |
97 | | - }, |
98 | | - |
99 | 176 | _updateItems: function() { |
100 | 177 | var newItems = Array.prototype.slice.call( |
101 | 178 | Polymer.dom(this.$.item).getDistributedNodes() |
|
116 | 193 | } |
117 | 194 | this._observeItems(); |
118 | 195 | this._setItems(newItems.map(function(item){ |
119 | | - return item.data |
| 196 | + return { |
| 197 | + label: item.label, |
| 198 | + amount: item.amount |
| 199 | + }; |
120 | 200 | })); |
121 | 201 | }, |
122 | 202 |
|
|
146 | 226 | currency: this.currency || (this.items.length && this.items[0].amount.currency) || 'USD' |
147 | 227 | }); |
148 | 228 | } |
149 | | - this._setTotal(total.data); |
| 229 | + this._setTotal({ |
| 230 | + label: total.label, |
| 231 | + amount: total.amount |
| 232 | + }); |
150 | 233 | }, |
151 | 234 |
|
152 | 235 | _computeMethodData: function() { |
153 | 236 | var methodData = []; |
154 | | - if (this.networks.length > 0) { |
| 237 | + if (this.networks.length) { |
155 | 238 | methodData.push({ |
156 | 239 | supportedMethods: this.networks |
157 | 240 | }); |
158 | | - methodData.push({ |
159 | | - supportedMethods: ['basic-card'], |
160 | | - data: {supportedNetworks: this.networks, supportedTypes: this.types}, |
161 | | - }); |
| 241 | + if (this.types.length) { |
| 242 | + methodData.push({ |
| 243 | + supportedMethods: ['basic-card'], |
| 244 | + data: { |
| 245 | + supportedNetworks: this.networks, |
| 246 | + supportedTypes: this.types |
| 247 | + } |
| 248 | + }); |
| 249 | + } |
162 | 250 | } |
163 | 251 | return methodData; |
164 | 252 | }, |
165 | 253 |
|
166 | 254 | _computeDetails: function(total, items) { |
167 | 255 | this.set('details.total', total); |
| 256 | + this.notifyPath('details.total.label'); |
| 257 | + this.notifyPath('details.total.amount.value'); |
| 258 | + this.notifyPath('details.total.amount.currency'); |
168 | 259 | this.set('details.displayItems', items); |
169 | 260 | }, |
170 | 261 |
|
| 262 | + /** |
| 263 | + * Construct a PaymentRequest using the supplied methodData list including any |
| 264 | + * payment method specific data, the payment details, and the payment options |
| 265 | + * |
| 266 | + * @return {PaymentRequest} |
| 267 | + */ |
171 | 268 | paymentRequest: function() { |
172 | | - debugger; |
173 | | - return new PaymentRequest(this.methodData, this.details); |
| 269 | + this._setLastPaymentRequest(new PaymentRequest(this.methodData, this.details)); |
| 270 | + return this.lastPaymentRequest; |
| 271 | + }, |
| 272 | + |
| 273 | + /** |
| 274 | + * Determine if the PaymentRequest object can be used to make a payment. |
| 275 | + * |
| 276 | + * @return {Promise} |
| 277 | + */ |
| 278 | + canMakePayment: function() { |
| 279 | + return (this.lastPaymentRequest || this.paymentRequest()).canMakePayment() |
| 280 | + .then(function(canMakePayment) { |
| 281 | + this._setLastError(null); |
| 282 | + this._setLastCanMakePayment(canMakePayment); |
| 283 | + if (canMakePayment) { |
| 284 | + event = 'can'; |
| 285 | + } else { |
| 286 | + event = 'cannot'; |
| 287 | + this._setLastPaymentRequest(null); |
| 288 | + } |
| 289 | + this.dispatchEvent(new CustomEvent(event + '-make-payment', { |
| 290 | + detail: canMakePayment |
| 291 | + })); |
| 292 | + }.bind(this)) |
| 293 | + .catch(function(error) { |
| 294 | + this._setLastError(error); |
| 295 | + this.dispatchEvent( |
| 296 | + new CustomEvent('error', { |
| 297 | + detail: error |
| 298 | + }) |
| 299 | + ); |
| 300 | + }.bind(this)); |
| 301 | + }, |
| 302 | + |
| 303 | + /** |
| 304 | + * Begin user interaction for the payment request. |
| 305 | + * |
| 306 | + * @return {Promise} |
| 307 | + */ |
| 308 | + show: function() { |
| 309 | + return (this.lastPaymentRequest || this.paymentRequest()).show() |
| 310 | + .then(function(paymentResponse) { |
| 311 | + this._setLastError(null); |
| 312 | + this._setLastPaymentResponse(paymentResponse); |
| 313 | + this.dispatchEvent( |
| 314 | + new CustomEvent('payment-response', { |
| 315 | + detail: paymentResponse |
| 316 | + }) |
| 317 | + ); |
| 318 | + }.bind(this)) |
| 319 | + .catch(function(error) { |
| 320 | + this._setLastError(error); |
| 321 | + this._setLastPaymentRequest(null); |
| 322 | + this._setLastPaymentResponse(null); |
| 323 | + this.dispatchEvent( |
| 324 | + new CustomEvent('error', { |
| 325 | + detail: error |
| 326 | + }) |
| 327 | + ); |
| 328 | + }.bind(this)); |
| 329 | + }, |
| 330 | + |
| 331 | + /** |
| 332 | + * Abort the payment request |
| 333 | + * @return {Promise} |
| 334 | + */ |
| 335 | + abort: function() { |
| 336 | + if (this.lastPaymentRequest) { |
| 337 | + return this.lastPaymentRequest.abort() |
| 338 | + .then(function() { |
| 339 | + this._setLastError(null); |
| 340 | + this._setLastPaymentRequest(null); |
| 341 | + this._setLastPaymentResponse(null); |
| 342 | + this.dispatchEvent( |
| 343 | + new CustomEvent('payment-aborted') |
| 344 | + ); |
| 345 | + }.bind(this)) |
| 346 | + .catch(function(error) { |
| 347 | + this._setLastError(error); |
| 348 | + this.dispatchEvent( |
| 349 | + new CustomEvent('error', { |
| 350 | + detail: error |
| 351 | + }) |
| 352 | + ); |
| 353 | + }.bind(this)); |
| 354 | + } else { |
| 355 | + // TODO: dispatch event to inform that there aren't any payment process. |
| 356 | + } |
174 | 357 | } |
175 | 358 |
|
176 | 359 | }); |
|
0 commit comments