Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "PaymentRequestManager.h"
8 : #include "PaymentRequestUtils.h"
9 : #include "mozilla/ClearOnShutdown.h"
10 : #include "mozilla/dom/ContentChild.h"
11 : #include "mozilla/dom/TabChild.h"
12 : #include "mozilla/dom/PaymentRequestChild.h"
13 : #include "nsContentUtils.h"
14 : #include "nsString.h"
15 :
16 : namespace mozilla {
17 : namespace dom {
18 : namespace {
19 :
20 : /*
21 : * Following Convert* functions are used for convert PaymentRequest structs
22 : * to transferable structs for IPC.
23 : */
24 : nsresult
25 0 : ConvertMethodData(const PaymentMethodData& aMethodData,
26 : IPCPaymentMethodData& aIPCMethodData)
27 : {
28 : // Convert JSObject to a serialized string
29 0 : nsAutoString serializedData;
30 0 : if (aMethodData.mData.WasPassed()) {
31 0 : JSContext* cx = nsContentUtils::GetCurrentJSContext();
32 0 : MOZ_ASSERT(cx);
33 0 : JS::RootedObject object(cx, aMethodData.mData.Value());
34 0 : nsresult rv = SerializeFromJSObject(cx, object, serializedData);
35 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
36 0 : return rv;
37 : }
38 : }
39 0 : aIPCMethodData = IPCPaymentMethodData(aMethodData.mSupportedMethods, serializedData);
40 0 : return NS_OK;
41 : }
42 :
43 : void
44 0 : ConvertCurrencyAmount(const PaymentCurrencyAmount& aAmount,
45 : IPCPaymentCurrencyAmount& aIPCCurrencyAmount)
46 : {
47 0 : aIPCCurrencyAmount = IPCPaymentCurrencyAmount(aAmount.mCurrency, aAmount.mValue);
48 0 : }
49 :
50 : void
51 0 : ConvertItem(const PaymentItem& aItem, IPCPaymentItem& aIPCItem)
52 : {
53 0 : IPCPaymentCurrencyAmount amount;
54 0 : ConvertCurrencyAmount(aItem.mAmount, amount);
55 0 : aIPCItem = IPCPaymentItem(aItem.mLabel, amount, aItem.mPending);
56 0 : }
57 :
58 : nsresult
59 0 : ConvertModifier(const PaymentDetailsModifier& aModifier,
60 : IPCPaymentDetailsModifier& aIPCModifier)
61 : {
62 : // Convert JSObject to a serialized string
63 0 : nsAutoString serializedData;
64 0 : if (aModifier.mData.WasPassed()) {
65 0 : JSContext* cx = nsContentUtils::GetCurrentJSContext();
66 0 : MOZ_ASSERT(cx);
67 0 : JS::RootedObject object(cx, aModifier.mData.Value());
68 0 : nsresult rv = SerializeFromJSObject(cx, object, serializedData);
69 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
70 0 : return rv;
71 : }
72 : }
73 :
74 0 : IPCPaymentItem total;
75 0 : ConvertItem(aModifier.mTotal, total);
76 :
77 0 : nsTArray<IPCPaymentItem> additionalDisplayItems;
78 0 : if (aModifier.mAdditionalDisplayItems.WasPassed()) {
79 0 : for (const PaymentItem& item : aModifier.mAdditionalDisplayItems.Value()) {
80 0 : IPCPaymentItem displayItem;
81 0 : ConvertItem(item, displayItem);
82 0 : additionalDisplayItems.AppendElement(displayItem);
83 : }
84 : }
85 0 : aIPCModifier = IPCPaymentDetailsModifier(aModifier.mSupportedMethods,
86 : total,
87 : additionalDisplayItems,
88 : serializedData,
89 0 : aModifier.mAdditionalDisplayItems.WasPassed());
90 0 : return NS_OK;
91 : }
92 :
93 : void
94 0 : ConvertShippingOption(const PaymentShippingOption& aOption,
95 : IPCPaymentShippingOption& aIPCOption)
96 : {
97 0 : IPCPaymentCurrencyAmount amount;
98 0 : ConvertCurrencyAmount(aOption.mAmount, amount);
99 0 : aIPCOption = IPCPaymentShippingOption(aOption.mId, aOption.mLabel, amount, aOption.mSelected);
100 0 : }
101 :
102 : nsresult
103 0 : ConvertDetailsBase(const PaymentDetailsBase& aDetails,
104 : nsTArray<IPCPaymentItem>& aDisplayItems,
105 : nsTArray<IPCPaymentShippingOption>& aShippingOptions,
106 : nsTArray<IPCPaymentDetailsModifier>& aModifiers,
107 : bool aResetShippingOptions)
108 : {
109 0 : if (aDetails.mDisplayItems.WasPassed()) {
110 0 : for (const PaymentItem& item : aDetails.mDisplayItems.Value()) {
111 0 : IPCPaymentItem displayItem;
112 0 : ConvertItem(item, displayItem);
113 0 : aDisplayItems.AppendElement(displayItem);
114 : }
115 : }
116 0 : if (aDetails.mShippingOptions.WasPassed() && !aResetShippingOptions) {
117 0 : for (const PaymentShippingOption& option : aDetails.mShippingOptions.Value()) {
118 0 : IPCPaymentShippingOption shippingOption;
119 0 : ConvertShippingOption(option, shippingOption);
120 0 : aShippingOptions.AppendElement(shippingOption);
121 : }
122 : }
123 0 : if (aDetails.mModifiers.WasPassed()) {
124 0 : for (const PaymentDetailsModifier& modifier : aDetails.mModifiers.Value()) {
125 0 : IPCPaymentDetailsModifier detailsModifier;
126 0 : nsresult rv = ConvertModifier(modifier, detailsModifier);
127 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
128 0 : return rv;
129 : }
130 0 : aModifiers.AppendElement(detailsModifier);
131 : }
132 : }
133 0 : return NS_OK;
134 : }
135 :
136 : nsresult
137 0 : ConvertDetailsInit(const PaymentDetailsInit& aDetails,
138 : IPCPaymentDetails& aIPCDetails,
139 : bool aResetShippingOptions)
140 : {
141 : // Convert PaymentDetailsBase members
142 0 : nsTArray<IPCPaymentItem> displayItems;
143 0 : nsTArray<IPCPaymentShippingOption> shippingOptions;
144 0 : nsTArray<IPCPaymentDetailsModifier> modifiers;
145 0 : nsresult rv = ConvertDetailsBase(aDetails, displayItems, shippingOptions, modifiers, aResetShippingOptions);
146 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
147 0 : return rv;
148 : }
149 :
150 : // Convert |id|
151 0 : nsString id(EmptyString());
152 0 : if (aDetails.mId.WasPassed()) {
153 0 : id = aDetails.mId.Value();
154 : }
155 :
156 : // Convert required |total|
157 0 : IPCPaymentItem total;
158 0 : ConvertItem(aDetails.mTotal, total);
159 :
160 0 : aIPCDetails = IPCPaymentDetails(id,
161 : total,
162 : displayItems,
163 : shippingOptions,
164 : modifiers,
165 : EmptyString(), // error message
166 0 : aDetails.mDisplayItems.WasPassed(),
167 0 : aDetails.mShippingOptions.WasPassed(),
168 0 : aDetails.mModifiers.WasPassed());
169 0 : return NS_OK;
170 : }
171 :
172 : nsresult
173 0 : ConvertDetailsUpdate(const PaymentDetailsUpdate& aDetails,
174 : IPCPaymentDetails& aIPCDetails)
175 : {
176 : // Convert PaymentDetailsBase members
177 0 : nsTArray<IPCPaymentItem> displayItems;
178 0 : nsTArray<IPCPaymentShippingOption> shippingOptions;
179 0 : nsTArray<IPCPaymentDetailsModifier> modifiers;
180 : // [TODO] Populate a boolean flag as aResetShippingOptions based on the
181 : // result of processing details.shippingOptions in UpdatePayment method.
182 0 : nsresult rv = ConvertDetailsBase(
183 0 : aDetails, displayItems, shippingOptions, modifiers, false);
184 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
185 0 : return rv;
186 : }
187 :
188 : // Convert required |total|
189 0 : IPCPaymentItem total;
190 0 : ConvertItem(aDetails.mTotal, total);
191 :
192 : // Convert |error|
193 0 : nsString error(EmptyString());
194 0 : if (aDetails.mError.WasPassed()) {
195 0 : error = aDetails.mError.Value();
196 : }
197 :
198 0 : aIPCDetails = IPCPaymentDetails(EmptyString(), // id
199 : total,
200 : displayItems,
201 : shippingOptions,
202 : modifiers,
203 : error,
204 0 : aDetails.mDisplayItems.WasPassed(),
205 0 : aDetails.mShippingOptions.WasPassed(),
206 0 : aDetails.mModifiers.WasPassed());
207 0 : return NS_OK;
208 : }
209 :
210 : void
211 0 : ConvertOptions(const PaymentOptions& aOptions,
212 : IPCPaymentOptions& aIPCOption)
213 : {
214 0 : uint8_t shippingTypeIndex = static_cast<uint8_t>(aOptions.mShippingType);
215 0 : nsString shippingType(NS_LITERAL_STRING("shipping"));
216 0 : if (shippingTypeIndex < ArrayLength(PaymentShippingTypeValues::strings)) {
217 0 : shippingType.AssignASCII(
218 0 : PaymentShippingTypeValues::strings[shippingTypeIndex].value);
219 : }
220 0 : aIPCOption = IPCPaymentOptions(aOptions.mRequestPayerName,
221 : aOptions.mRequestPayerEmail,
222 : aOptions.mRequestPayerPhone,
223 : aOptions.mRequestShipping,
224 0 : shippingType);
225 0 : }
226 : } // end of namespace
227 :
228 : /* PaymentRequestManager */
229 :
230 3 : StaticRefPtr<PaymentRequestManager> gPaymentManager;
231 :
232 : nsresult
233 0 : PaymentRequestManager::GetPaymentChild(PaymentRequest* aRequest,
234 : PaymentRequestChild** aChild)
235 : {
236 0 : NS_ENSURE_ARG_POINTER(aRequest);
237 0 : NS_ENSURE_ARG_POINTER(aChild);
238 0 : *aChild = nullptr;
239 :
240 0 : RefPtr<PaymentRequestChild> paymentChild;
241 0 : if (mPaymentChildHash.Get(aRequest, getter_AddRefs(paymentChild))) {
242 0 : paymentChild.forget(aChild);
243 0 : return NS_OK;
244 : }
245 :
246 0 : nsPIDOMWindowInner* win = aRequest->GetOwner();
247 0 : NS_ENSURE_TRUE(win, NS_ERROR_FAILURE);
248 0 : TabChild* tabChild = TabChild::GetFrom(win->GetDocShell());
249 0 : NS_ENSURE_TRUE(tabChild, NS_ERROR_FAILURE);
250 0 : nsAutoString requestId;
251 0 : aRequest->GetInternalId(requestId);
252 :
253 : // Only one payment request can interact with user at the same time.
254 : // Before we create a new PaymentRequestChild, make sure there is no other
255 : // payment request are interacting on the same tab.
256 0 : for (auto iter = mPaymentChildHash.ConstIter(); !iter.Done(); iter.Next()) {
257 0 : RefPtr<PaymentRequest> request = iter.Key();
258 0 : if (request->Equals(requestId)) {
259 0 : continue;
260 : }
261 0 : nsPIDOMWindowInner* requestOwner = request->GetOwner();
262 0 : NS_ENSURE_TRUE(requestOwner, NS_ERROR_FAILURE);
263 0 : TabChild* tmpChild = TabChild::GetFrom(requestOwner->GetDocShell());
264 0 : NS_ENSURE_TRUE(tmpChild, NS_ERROR_FAILURE);
265 0 : if (tmpChild->GetTabId() == tabChild->GetTabId()) {
266 0 : return NS_ERROR_FAILURE;
267 : }
268 : }
269 :
270 0 : paymentChild = new PaymentRequestChild();
271 0 : tabChild->SendPPaymentRequestConstructor(paymentChild);
272 0 : if (!mPaymentChildHash.Put(aRequest, paymentChild, mozilla::fallible) ) {
273 0 : return NS_ERROR_OUT_OF_MEMORY;
274 : }
275 0 : paymentChild.forget(aChild);
276 0 : return NS_OK;
277 : }
278 :
279 : nsresult
280 0 : PaymentRequestManager::ReleasePaymentChild(PaymentRequestChild* aPaymentChild)
281 : {
282 0 : NS_ENSURE_ARG_POINTER(aPaymentChild);
283 0 : for (auto iter = mPaymentChildHash.Iter(); !iter.Done(); iter.Next()) {
284 0 : RefPtr<PaymentRequestChild> child = iter.Data();
285 0 : if (NS_WARN_IF(!child)) {
286 0 : return NS_ERROR_FAILURE;
287 : }
288 0 : if (child == aPaymentChild) {
289 0 : iter.Remove();
290 0 : return NS_OK;
291 : }
292 : }
293 0 : return NS_OK;
294 : }
295 :
296 : nsresult
297 0 : PaymentRequestManager::ReleasePaymentChild(PaymentRequest* aRequest)
298 : {
299 0 : NS_ENSURE_ARG_POINTER(aRequest);
300 :
301 0 : RefPtr<PaymentRequestChild> paymentChild;
302 0 : if(!mPaymentChildHash.Remove(aRequest, getter_AddRefs(paymentChild))) {
303 0 : return NS_ERROR_FAILURE;
304 : }
305 0 : if (NS_WARN_IF(!paymentChild)) {
306 0 : return NS_ERROR_FAILURE;
307 : }
308 0 : paymentChild->MaybeDelete();
309 0 : return NS_OK;
310 : }
311 :
312 : nsresult
313 0 : PaymentRequestManager::SendRequestPayment(PaymentRequest* aRequest,
314 : const IPCPaymentActionRequest& aAction,
315 : bool aReleaseAfterSend)
316 : {
317 0 : RefPtr<PaymentRequestChild> requestChild;
318 0 : nsresult rv = GetPaymentChild(aRequest, getter_AddRefs(requestChild));
319 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
320 0 : return rv;
321 : }
322 :
323 0 : rv = requestChild->RequestPayment(aAction);
324 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
325 0 : return rv;
326 : }
327 :
328 0 : if (aReleaseAfterSend) {
329 0 : rv = ReleasePaymentChild(aRequest);
330 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
331 0 : return rv;
332 : }
333 : }
334 0 : return NS_OK;
335 : }
336 :
337 : already_AddRefed<PaymentRequestManager>
338 0 : PaymentRequestManager::GetSingleton()
339 : {
340 0 : if (!gPaymentManager) {
341 0 : gPaymentManager = new PaymentRequestManager();
342 0 : ClearOnShutdown(&gPaymentManager);
343 : }
344 0 : RefPtr<PaymentRequestManager> manager = gPaymentManager;
345 0 : return manager.forget();
346 : }
347 :
348 : already_AddRefed<PaymentRequest>
349 0 : PaymentRequestManager::GetPaymentRequestById(const nsAString& aRequestId)
350 : {
351 0 : for (const RefPtr<PaymentRequest>& request : mRequestQueue) {
352 0 : if (request->Equals(aRequestId)) {
353 0 : RefPtr<PaymentRequest> paymentRequest = request;
354 0 : return paymentRequest.forget();
355 : }
356 : }
357 0 : return nullptr;
358 : }
359 :
360 : void
361 0 : GetSelectedShippingOption(const PaymentDetailsInit& aDetails,
362 : nsAString& aOption,
363 : bool* aResetOptions)
364 : {
365 0 : SetDOMStringToNull(aOption);
366 0 : if (!aDetails.mShippingOptions.WasPassed()) {
367 0 : return;
368 : }
369 :
370 0 : nsTArray<nsString> seenIDs;
371 : const Sequence<PaymentShippingOption>& shippingOptions =
372 0 : aDetails.mShippingOptions.Value();
373 0 : for (const PaymentShippingOption& shippingOption : shippingOptions) {
374 : // If there are duplicate IDs present in the shippingOptions, reset aOption
375 : // to null and set resetOptions flag to reset details.shippingOptions later
376 : // when converting to IPC structure.
377 0 : if (seenIDs.Contains(shippingOption.mId)) {
378 0 : SetDOMStringToNull(aOption);
379 0 : *aResetOptions = true;
380 0 : return;
381 : }
382 0 : seenIDs.AppendElement(shippingOption.mId);
383 :
384 : // set aOption to last selected option's ID
385 0 : if (shippingOption.mSelected) {
386 0 : aOption = shippingOption.mId;
387 : }
388 : }
389 : }
390 :
391 : nsresult
392 0 : PaymentRequestManager::CreatePayment(nsPIDOMWindowInner* aWindow,
393 : const Sequence<PaymentMethodData>& aMethodData,
394 : const PaymentDetailsInit& aDetails,
395 : const PaymentOptions& aOptions,
396 : PaymentRequest** aRequest)
397 : {
398 0 : MOZ_ASSERT(NS_IsMainThread());
399 0 : NS_ENSURE_ARG_POINTER(aRequest);
400 0 : *aRequest = nullptr;
401 : nsresult rv;
402 :
403 0 : RefPtr<PaymentRequest> request = PaymentRequest::CreatePaymentRequest(aWindow, rv);
404 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
405 0 : return rv;
406 : }
407 :
408 : /*
409 : * Set request's |mId| to details.id if details.id exists.
410 : * Otherwise, set |mId| to internal id.
411 : */
412 0 : nsAutoString requestId;
413 0 : if (aDetails.mId.WasPassed() && !aDetails.mId.Value().IsEmpty()) {
414 0 : requestId = aDetails.mId.Value();
415 : } else {
416 0 : request->GetInternalId(requestId);
417 : }
418 0 : request->SetId(requestId);
419 :
420 : /*
421 : * Set request's mShippingOption to last selected option's ID if
422 : * details.shippingOptions exists and IDs of all options are unique.
423 : * Otherwise, set mShippingOption to null and set the resetShippingOptions
424 : * flag to reset details.shippingOptions to an empty array later when
425 : * converting details to IPC structure.
426 : */
427 0 : nsAutoString shippingOption;
428 0 : bool resetShippingOptions = false;
429 0 : GetSelectedShippingOption(aDetails, shippingOption, &resetShippingOptions);
430 0 : request->SetShippingOption(shippingOption);
431 :
432 : /*
433 : * Set request's |mShippingType| if shipping is required.
434 : */
435 0 : if (aOptions.mRequestShipping) {
436 0 : request->SetShippingType(
437 0 : Nullable<PaymentShippingType>(aOptions.mShippingType));
438 : }
439 :
440 0 : nsAutoString internalId;
441 0 : request->GetInternalId(internalId);
442 :
443 0 : nsTArray<IPCPaymentMethodData> methodData;
444 0 : for (const PaymentMethodData& data : aMethodData) {
445 0 : IPCPaymentMethodData ipcMethodData;
446 0 : rv = ConvertMethodData(data, ipcMethodData);
447 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
448 0 : return rv;
449 : }
450 0 : methodData.AppendElement(ipcMethodData);
451 : }
452 :
453 0 : IPCPaymentDetails details;
454 0 : rv = ConvertDetailsInit(aDetails, details, resetShippingOptions);
455 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
456 0 : return rv;
457 : }
458 :
459 0 : IPCPaymentOptions options;
460 0 : ConvertOptions(aOptions, options);
461 :
462 : IPCPaymentCreateActionRequest action(internalId,
463 : methodData,
464 : details,
465 0 : options);
466 :
467 0 : rv = SendRequestPayment(request, action, true);
468 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
469 0 : return rv;
470 : }
471 0 : mRequestQueue.AppendElement(request);
472 0 : request.forget(aRequest);
473 0 : return NS_OK;
474 : }
475 :
476 : nsresult
477 0 : PaymentRequestManager::CanMakePayment(const nsAString& aRequestId)
478 : {
479 0 : RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
480 0 : if (!request) {
481 0 : return NS_ERROR_FAILURE;
482 : }
483 :
484 0 : nsAutoString requestId(aRequestId);
485 0 : IPCPaymentCanMakeActionRequest action(requestId);
486 :
487 0 : return SendRequestPayment(request, action);
488 : }
489 :
490 : nsresult
491 0 : PaymentRequestManager::ShowPayment(const nsAString& aRequestId)
492 : {
493 0 : RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
494 0 : if (!request) {
495 0 : return NS_ERROR_FAILURE;
496 : }
497 :
498 0 : nsAutoString requestId(aRequestId);
499 0 : IPCPaymentShowActionRequest action(requestId);
500 :
501 0 : return SendRequestPayment(request, action);
502 : }
503 :
504 : nsresult
505 0 : PaymentRequestManager::AbortPayment(const nsAString& aRequestId)
506 : {
507 0 : RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
508 0 : if (!request) {
509 0 : return NS_ERROR_FAILURE;
510 : }
511 :
512 0 : nsAutoString requestId(aRequestId);
513 0 : IPCPaymentAbortActionRequest action(requestId);
514 :
515 0 : return SendRequestPayment(request, action);
516 : }
517 :
518 : nsresult
519 0 : PaymentRequestManager::CompletePayment(const nsAString& aRequestId,
520 : const PaymentComplete& aComplete)
521 : {
522 0 : RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
523 0 : if (!request) {
524 0 : return NS_ERROR_FAILURE;
525 : }
526 :
527 0 : nsString completeStatusString(NS_LITERAL_STRING("unknown"));
528 0 : uint8_t completeIndex = static_cast<uint8_t>(aComplete);
529 0 : if (completeIndex < ArrayLength(PaymentCompleteValues::strings)) {
530 0 : completeStatusString.AssignASCII(
531 0 : PaymentCompleteValues::strings[completeIndex].value);
532 : }
533 :
534 0 : nsAutoString requestId(aRequestId);
535 0 : IPCPaymentCompleteActionRequest action(requestId, completeStatusString);
536 :
537 0 : return SendRequestPayment(request, action);
538 : }
539 :
540 : nsresult
541 0 : PaymentRequestManager::UpdatePayment(const nsAString& aRequestId,
542 : const PaymentDetailsUpdate& aDetails)
543 : {
544 0 : RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
545 0 : if (!request) {
546 0 : return NS_ERROR_UNEXPECTED;
547 : }
548 :
549 : // [TODO] Process details.shippingOptions if presented.
550 : // 1) Check if there are duplicate IDs in details.shippingOptions,
551 : // if so, reset details.shippingOptions to an empty sequence.
552 : // 2) Set request's selectedShippingOption to the ID of last selected
553 : // option.
554 :
555 0 : IPCPaymentDetails details;
556 0 : nsresult rv = ConvertDetailsUpdate(aDetails, details);
557 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
558 0 : return rv;
559 : }
560 :
561 0 : nsAutoString requestId(aRequestId);
562 0 : IPCPaymentUpdateActionRequest action(requestId, details);
563 0 : return SendRequestPayment(request, action);
564 : }
565 :
566 : nsresult
567 0 : PaymentRequestManager::RespondPayment(const IPCPaymentActionResponse& aResponse)
568 : {
569 0 : switch (aResponse.type()) {
570 : case IPCPaymentActionResponse::TIPCPaymentCanMakeActionResponse: {
571 0 : const IPCPaymentCanMakeActionResponse& response = aResponse;
572 0 : RefPtr<PaymentRequest> request = GetPaymentRequestById(response.requestId());
573 0 : if (NS_WARN_IF(!request)) {
574 0 : return NS_ERROR_FAILURE;
575 : }
576 0 : request->RespondCanMakePayment(response.result());
577 0 : nsresult rv = ReleasePaymentChild(request);
578 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
579 0 : return rv;
580 : }
581 0 : break;
582 : }
583 : case IPCPaymentActionResponse::TIPCPaymentShowActionResponse: {
584 0 : const IPCPaymentShowActionResponse& response = aResponse;
585 0 : RefPtr<PaymentRequest> request = GetPaymentRequestById(response.requestId());
586 0 : if (NS_WARN_IF(!request)) {
587 0 : return NS_ERROR_FAILURE;
588 : }
589 0 : request->RespondShowPayment(response.isAccepted(),
590 0 : response.methodName(),
591 0 : response.data(),
592 0 : response.payerName(),
593 0 : response.payerEmail(),
594 0 : response.payerPhone());
595 0 : if (!response.isAccepted()) {
596 0 : mRequestQueue.RemoveElement(request);
597 0 : nsresult rv = ReleasePaymentChild(request);
598 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
599 0 : return rv;
600 : }
601 : }
602 0 : break;
603 : }
604 : case IPCPaymentActionResponse::TIPCPaymentAbortActionResponse: {
605 0 : const IPCPaymentAbortActionResponse& response = aResponse;
606 0 : RefPtr<PaymentRequest> request = GetPaymentRequestById(response.requestId());
607 0 : if (NS_WARN_IF(!request)) {
608 0 : return NS_ERROR_FAILURE;
609 : }
610 0 : request->RespondAbortPayment(response.isSucceeded());
611 0 : if (response.isSucceeded()) {
612 0 : mRequestQueue.RemoveElement(request);
613 0 : nsresult rv = ReleasePaymentChild(request);
614 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
615 0 : return rv;
616 : }
617 : }
618 0 : break;
619 : }
620 : case IPCPaymentActionResponse::TIPCPaymentCompleteActionResponse: {
621 0 : const IPCPaymentCompleteActionResponse& response = aResponse;
622 0 : RefPtr<PaymentRequest> request = GetPaymentRequestById(response.requestId());
623 0 : if (NS_WARN_IF(!request)) {
624 0 : return NS_ERROR_FAILURE;
625 : }
626 0 : request->RespondComplete();
627 0 : mRequestQueue.RemoveElement(request);
628 0 : nsresult rv = ReleasePaymentChild(request);
629 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
630 0 : return rv;
631 : }
632 0 : break;
633 : }
634 : default: {
635 0 : return NS_ERROR_FAILURE;
636 : }
637 : }
638 0 : return NS_OK;
639 : }
640 :
641 : nsresult
642 0 : PaymentRequestManager::ChangeShippingAddress(const nsAString& aRequestId,
643 : const IPCPaymentAddress& aAddress)
644 : {
645 0 : RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
646 0 : if (NS_WARN_IF(!request)) {
647 0 : return NS_ERROR_FAILURE;
648 : }
649 0 : return request->UpdateShippingAddress(aAddress.country(),
650 : aAddress.addressLine(),
651 0 : aAddress.region(),
652 0 : aAddress.city(),
653 0 : aAddress.dependentLocality(),
654 0 : aAddress.postalCode(),
655 0 : aAddress.sortingCode(),
656 0 : aAddress.languageCode(),
657 0 : aAddress.organization(),
658 0 : aAddress.recipient(),
659 0 : aAddress.phone());
660 : }
661 :
662 : nsresult
663 0 : PaymentRequestManager::ChangeShippingOption(const nsAString& aRequestId,
664 : const nsAString& aOption)
665 : {
666 0 : RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
667 0 : if (NS_WARN_IF(!request)) {
668 0 : return NS_ERROR_FAILURE;
669 : }
670 0 : return request->UpdateShippingOption(aOption);
671 : }
672 :
673 : } // end of namespace dom
674 : } // end of namespace mozilla
|