зеркало из https://github.com/mozilla/gecko-dev.git
607 строки
19 KiB
C++
607 строки
19 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "BasicCardPayment.h"
|
|
#include "mozilla/ClearOnShutdown.h"
|
|
#include "mozilla/dom/BasicCardPaymentBinding.h"
|
|
#include "mozilla/dom/PaymentRequestParent.h"
|
|
#include "nsArrayUtils.h"
|
|
#include "nsComponentManagerUtils.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsIMutableArray.h"
|
|
#include "nsServiceManagerUtils.h"
|
|
#include "nsSimpleEnumerator.h"
|
|
#include "PaymentRequestService.h"
|
|
|
|
namespace mozilla::dom {
|
|
|
|
StaticRefPtr<PaymentRequestService> gPaymentService;
|
|
|
|
namespace {
|
|
|
|
class PaymentRequestEnumerator final : public nsSimpleEnumerator {
|
|
public:
|
|
NS_DECL_NSISIMPLEENUMERATOR
|
|
|
|
PaymentRequestEnumerator() : mIndex(0) {}
|
|
|
|
const nsID& DefaultInterface() override {
|
|
return NS_GET_IID(nsIPaymentRequest);
|
|
}
|
|
|
|
private:
|
|
~PaymentRequestEnumerator() override = default;
|
|
uint32_t mIndex;
|
|
};
|
|
|
|
NS_IMETHODIMP
|
|
PaymentRequestEnumerator::HasMoreElements(bool* aReturn) {
|
|
NS_ENSURE_ARG_POINTER(aReturn);
|
|
*aReturn = false;
|
|
if (NS_WARN_IF(!gPaymentService)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
RefPtr<PaymentRequestService> service = gPaymentService;
|
|
*aReturn = mIndex < service->NumPayments();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PaymentRequestEnumerator::GetNext(nsISupports** aItem) {
|
|
NS_ENSURE_ARG_POINTER(aItem);
|
|
if (NS_WARN_IF(!gPaymentService)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
RefPtr<payments::PaymentRequest> rowRequest =
|
|
gPaymentService->GetPaymentRequestByIndex(mIndex);
|
|
if (!rowRequest) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
mIndex++;
|
|
rowRequest.forget(aItem);
|
|
return NS_OK;
|
|
}
|
|
|
|
} // end of anonymous namespace
|
|
|
|
/* PaymentRequestService */
|
|
|
|
NS_IMPL_ISUPPORTS(PaymentRequestService, nsIPaymentRequestService)
|
|
|
|
already_AddRefed<PaymentRequestService> PaymentRequestService::GetSingleton() {
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
if (!gPaymentService) {
|
|
gPaymentService = new PaymentRequestService();
|
|
ClearOnShutdown(&gPaymentService);
|
|
}
|
|
RefPtr<PaymentRequestService> service = gPaymentService;
|
|
return service.forget();
|
|
}
|
|
|
|
uint32_t PaymentRequestService::NumPayments() const {
|
|
return mRequestQueue.Length();
|
|
}
|
|
|
|
already_AddRefed<payments::PaymentRequest>
|
|
PaymentRequestService::GetPaymentRequestByIndex(const uint32_t aIndex) {
|
|
if (aIndex >= mRequestQueue.Length()) {
|
|
return nullptr;
|
|
}
|
|
RefPtr<payments::PaymentRequest> request = mRequestQueue[aIndex];
|
|
MOZ_ASSERT(request);
|
|
return request.forget();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PaymentRequestService::GetPaymentRequestById(const nsAString& aRequestId,
|
|
nsIPaymentRequest** aRequest) {
|
|
NS_ENSURE_ARG_POINTER(aRequest);
|
|
*aRequest = nullptr;
|
|
RefPtr<payments::PaymentRequest> rowRequest;
|
|
nsresult rv = GetPaymentRequestById(aRequestId, getter_AddRefs(rowRequest));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
rowRequest.forget(aRequest);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult PaymentRequestService::GetPaymentRequestById(
|
|
const nsAString& aRequestId, payments::PaymentRequest** aRequest) {
|
|
NS_ENSURE_ARG_POINTER(aRequest);
|
|
*aRequest = nullptr;
|
|
uint32_t numRequests = mRequestQueue.Length();
|
|
for (uint32_t index = 0; index < numRequests; ++index) {
|
|
RefPtr<payments::PaymentRequest> request = mRequestQueue[index];
|
|
MOZ_ASSERT(request);
|
|
nsAutoString requestId;
|
|
nsresult rv = request->GetRequestId(requestId);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if (requestId == aRequestId) {
|
|
request.forget(aRequest);
|
|
break;
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PaymentRequestService::Enumerate(nsISimpleEnumerator** aEnumerator) {
|
|
NS_ENSURE_ARG_POINTER(aEnumerator);
|
|
nsCOMPtr<nsISimpleEnumerator> enumerator = new PaymentRequestEnumerator();
|
|
enumerator.forget(aEnumerator);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PaymentRequestService::Cleanup() {
|
|
mRequestQueue.Clear();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PaymentRequestService::SetTestingUIService(nsIPaymentUIService* aUIService) {
|
|
// aUIService can be nullptr
|
|
mTestingUIService = aUIService;
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult PaymentRequestService::LaunchUIAction(const nsAString& aRequestId,
|
|
uint32_t aActionType) {
|
|
nsCOMPtr<nsIPaymentUIService> uiService;
|
|
nsresult rv;
|
|
if (mTestingUIService) {
|
|
uiService = mTestingUIService;
|
|
} else {
|
|
uiService = do_GetService(NS_PAYMENT_UI_SERVICE_CONTRACT_ID, &rv);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
}
|
|
switch (aActionType) {
|
|
case IPCPaymentActionRequest::TIPCPaymentShowActionRequest: {
|
|
rv = uiService->ShowPayment(aRequestId);
|
|
break;
|
|
}
|
|
case IPCPaymentActionRequest::TIPCPaymentAbortActionRequest: {
|
|
rv = uiService->AbortPayment(aRequestId);
|
|
break;
|
|
}
|
|
case IPCPaymentActionRequest::TIPCPaymentCompleteActionRequest: {
|
|
rv = uiService->CompletePayment(aRequestId);
|
|
break;
|
|
}
|
|
case IPCPaymentActionRequest::TIPCPaymentUpdateActionRequest: {
|
|
rv = uiService->UpdatePayment(aRequestId);
|
|
break;
|
|
}
|
|
case IPCPaymentActionRequest::TIPCPaymentCloseActionRequest: {
|
|
rv = uiService->ClosePayment(aRequestId);
|
|
break;
|
|
}
|
|
default: {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
}
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult PaymentRequestService::RequestPayment(
|
|
const nsAString& aRequestId, const IPCPaymentActionRequest& aAction,
|
|
PaymentRequestParent* aIPC) {
|
|
NS_ENSURE_ARG_POINTER(aIPC);
|
|
|
|
nsresult rv = NS_OK;
|
|
uint32_t type = aAction.type();
|
|
|
|
RefPtr<payments::PaymentRequest> request;
|
|
if (type != IPCPaymentActionRequest::TIPCPaymentCreateActionRequest) {
|
|
rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
if (!request &&
|
|
type != IPCPaymentActionRequest::TIPCPaymentCloseActionRequest) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
if (request) {
|
|
request->SetIPC(aIPC);
|
|
}
|
|
}
|
|
|
|
switch (type) {
|
|
case IPCPaymentActionRequest::TIPCPaymentCreateActionRequest: {
|
|
MOZ_ASSERT(!request);
|
|
const IPCPaymentCreateActionRequest& action = aAction;
|
|
nsCOMPtr<nsIMutableArray> methodData =
|
|
do_CreateInstance(NS_ARRAY_CONTRACTID);
|
|
MOZ_ASSERT(methodData);
|
|
for (IPCPaymentMethodData data : action.methodData()) {
|
|
nsCOMPtr<nsIPaymentMethodData> method;
|
|
rv = payments::PaymentMethodData::Create(data, getter_AddRefs(method));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
rv = methodData->AppendElement(method);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
}
|
|
nsCOMPtr<nsIPaymentDetails> details;
|
|
rv = payments::PaymentDetails::Create(action.details(),
|
|
getter_AddRefs(details));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
nsCOMPtr<nsIPaymentOptions> options;
|
|
rv = payments::PaymentOptions::Create(action.options(),
|
|
getter_AddRefs(options));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
RefPtr<payments::PaymentRequest> request = new payments::PaymentRequest(
|
|
action.topOuterWindowId(), aRequestId, action.topLevelPrincipal(),
|
|
methodData, details, options, action.shippingOption());
|
|
|
|
if (!mRequestQueue.AppendElement(request, mozilla::fallible)) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
break;
|
|
}
|
|
case IPCPaymentActionRequest::TIPCPaymentCanMakeActionRequest: {
|
|
nsCOMPtr<nsIPaymentCanMakeActionResponse> canMakeResponse =
|
|
do_CreateInstance(NS_PAYMENT_CANMAKE_ACTION_RESPONSE_CONTRACT_ID);
|
|
MOZ_ASSERT(canMakeResponse);
|
|
rv = canMakeResponse->Init(aRequestId, CanMakePayment(aRequestId));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
rv = RespondPayment(canMakeResponse.get());
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
break;
|
|
}
|
|
case IPCPaymentActionRequest::TIPCPaymentShowActionRequest: {
|
|
const IPCPaymentShowActionRequest& action = aAction;
|
|
rv = ShowPayment(aRequestId, action.isUpdating());
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
break;
|
|
}
|
|
case IPCPaymentActionRequest::TIPCPaymentAbortActionRequest: {
|
|
MOZ_ASSERT(request);
|
|
request->SetState(payments::PaymentRequest::eInteractive);
|
|
rv = LaunchUIAction(aRequestId, type);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
break;
|
|
}
|
|
case IPCPaymentActionRequest::TIPCPaymentCompleteActionRequest: {
|
|
MOZ_ASSERT(request);
|
|
const IPCPaymentCompleteActionRequest& action = aAction;
|
|
request->SetCompleteStatus(action.completeStatus());
|
|
rv = LaunchUIAction(aRequestId, type);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
break;
|
|
}
|
|
case IPCPaymentActionRequest::TIPCPaymentUpdateActionRequest: {
|
|
const IPCPaymentUpdateActionRequest& action = aAction;
|
|
nsCOMPtr<nsIPaymentDetails> details;
|
|
rv = payments::PaymentDetails::Create(action.details(),
|
|
getter_AddRefs(details));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
MOZ_ASSERT(request);
|
|
rv = request->UpdatePaymentDetails(details, action.shippingOption());
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
nsAutoString completeStatus;
|
|
rv = request->GetCompleteStatus(completeStatus);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
if (completeStatus.Equals(u"initial"_ns)) {
|
|
request->SetCompleteStatus(u""_ns);
|
|
}
|
|
MOZ_ASSERT(mShowingRequest && mShowingRequest == request);
|
|
rv = LaunchUIAction(aRequestId, type);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
break;
|
|
}
|
|
case IPCPaymentActionRequest::TIPCPaymentCloseActionRequest: {
|
|
rv = LaunchUIAction(aRequestId, type);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
if (mShowingRequest == request) {
|
|
mShowingRequest = nullptr;
|
|
}
|
|
mRequestQueue.RemoveElement(request);
|
|
break;
|
|
}
|
|
case IPCPaymentActionRequest::TIPCPaymentRetryActionRequest: {
|
|
const IPCPaymentRetryActionRequest& action = aAction;
|
|
MOZ_ASSERT(request);
|
|
request->UpdateErrors(action.error(), action.payerErrors(),
|
|
action.paymentMethodErrors(),
|
|
action.shippingAddressErrors());
|
|
request->SetState(payments::PaymentRequest::eInteractive);
|
|
MOZ_ASSERT(mShowingRequest == request);
|
|
rv = LaunchUIAction(
|
|
aRequestId, IPCPaymentActionRequest::TIPCPaymentUpdateActionRequest);
|
|
break;
|
|
}
|
|
default: {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PaymentRequestService::RespondPayment(nsIPaymentActionResponse* aResponse) {
|
|
NS_ENSURE_ARG_POINTER(aResponse);
|
|
nsAutoString requestId;
|
|
nsresult rv = aResponse->GetRequestId(requestId);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
RefPtr<payments::PaymentRequest> request;
|
|
rv = GetPaymentRequestById(requestId, getter_AddRefs(request));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
if (!request) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
uint32_t type;
|
|
rv = aResponse->GetType(&type);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// PaymentRequest can only be responded when
|
|
// 1. the state is eInteractive
|
|
// 2. the state is eClosed and response type is COMPLETE_ACTION
|
|
// 3. the state is eCreated and response type is CANMAKE_ACTION
|
|
payments::PaymentRequest::eState state = request->GetState();
|
|
bool canBeResponded = (state == payments::PaymentRequest::eInteractive) ||
|
|
(state == payments::PaymentRequest::eClosed &&
|
|
type == nsIPaymentActionResponse::COMPLETE_ACTION) ||
|
|
(state == payments::PaymentRequest::eCreated &&
|
|
type == nsIPaymentActionResponse::CANMAKE_ACTION);
|
|
if (!canBeResponded) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
if (!request->GetIPC()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
rv = request->GetIPC()->RespondPayment(aResponse);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
|
|
// Remove PaymentRequest from mRequestQueue while receive succeeded abort
|
|
// response or complete response
|
|
switch (type) {
|
|
case nsIPaymentActionResponse::ABORT_ACTION: {
|
|
nsCOMPtr<nsIPaymentAbortActionResponse> response =
|
|
do_QueryInterface(aResponse);
|
|
MOZ_ASSERT(response);
|
|
bool isSucceeded;
|
|
rv = response->IsSucceeded(&isSucceeded);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
mShowingRequest = nullptr;
|
|
if (isSucceeded) {
|
|
mRequestQueue.RemoveElement(request);
|
|
request->SetState(payments::PaymentRequest::eClosed);
|
|
}
|
|
break;
|
|
}
|
|
case nsIPaymentActionResponse::SHOW_ACTION: {
|
|
request->SetState(payments::PaymentRequest::eClosed);
|
|
nsCOMPtr<nsIPaymentShowActionResponse> response =
|
|
do_QueryInterface(aResponse);
|
|
MOZ_ASSERT(response);
|
|
uint32_t acceptStatus;
|
|
rv = response->GetAcceptStatus(&acceptStatus);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if (acceptStatus != nsIPaymentActionResponse::PAYMENT_ACCEPTED) {
|
|
// Check if rejecting the showing PaymentRequest.
|
|
// If yes, set mShowingRequest as nullptr.
|
|
if (mShowingRequest == request) {
|
|
mShowingRequest = nullptr;
|
|
}
|
|
mRequestQueue.RemoveElement(request);
|
|
}
|
|
break;
|
|
}
|
|
case nsIPaymentActionResponse::COMPLETE_ACTION: {
|
|
mShowingRequest = nullptr;
|
|
mRequestQueue.RemoveElement(request);
|
|
break;
|
|
}
|
|
default: {
|
|
break;
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PaymentRequestService::ChangeShippingAddress(const nsAString& aRequestId,
|
|
nsIPaymentAddress* aAddress) {
|
|
RefPtr<payments::PaymentRequest> request;
|
|
nsresult rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
if (!request) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
if (request->GetState() != payments::PaymentRequest::eInteractive) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
if (!request->GetIPC()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
rv = request->GetIPC()->ChangeShippingAddress(aRequestId, aAddress);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PaymentRequestService::ChangeShippingOption(const nsAString& aRequestId,
|
|
const nsAString& aOption) {
|
|
RefPtr<payments::PaymentRequest> request;
|
|
nsresult rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
if (!request) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
if (request->GetState() != payments::PaymentRequest::eInteractive) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
if (!request->GetIPC()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
rv = request->GetIPC()->ChangeShippingOption(aRequestId, aOption);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PaymentRequestService::ChangePayerDetail(const nsAString& aRequestId,
|
|
const nsAString& aPayerName,
|
|
const nsAString& aPayerEmail,
|
|
const nsAString& aPayerPhone) {
|
|
RefPtr<payments::PaymentRequest> request;
|
|
nsresult rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
MOZ_ASSERT(request);
|
|
if (!request->GetIPC()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
rv = request->GetIPC()->ChangePayerDetail(aRequestId, aPayerName, aPayerEmail,
|
|
aPayerPhone);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
PaymentRequestService::ChangePaymentMethod(
|
|
const nsAString& aRequestId, const nsAString& aMethodName,
|
|
nsIMethodChangeDetails* aMethodDetails) {
|
|
RefPtr<payments::PaymentRequest> request;
|
|
nsresult rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
if (!request) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
if (request->GetState() != payments::PaymentRequest::eInteractive) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
if (!request->GetIPC()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
rv = request->GetIPC()->ChangePaymentMethod(aRequestId, aMethodName,
|
|
aMethodDetails);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
bool PaymentRequestService::CanMakePayment(const nsAString& aRequestId) {
|
|
/*
|
|
* TODO: Check third party payment app support by traversing all
|
|
* registered third party payment apps.
|
|
*/
|
|
return IsBasicCardPayment(aRequestId);
|
|
}
|
|
|
|
nsresult PaymentRequestService::ShowPayment(const nsAString& aRequestId,
|
|
bool aIsUpdating) {
|
|
nsresult rv;
|
|
RefPtr<payments::PaymentRequest> request;
|
|
rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
MOZ_ASSERT(request);
|
|
request->SetState(payments::PaymentRequest::eInteractive);
|
|
if (aIsUpdating) {
|
|
request->SetCompleteStatus(u"initial"_ns);
|
|
}
|
|
|
|
if (mShowingRequest || !CanMakePayment(aRequestId)) {
|
|
uint32_t responseStatus;
|
|
if (mShowingRequest) {
|
|
responseStatus = nsIPaymentActionResponse::PAYMENT_REJECTED;
|
|
} else {
|
|
responseStatus = nsIPaymentActionResponse::PAYMENT_NOTSUPPORTED;
|
|
}
|
|
nsCOMPtr<nsIPaymentShowActionResponse> showResponse =
|
|
do_CreateInstance(NS_PAYMENT_SHOW_ACTION_RESPONSE_CONTRACT_ID);
|
|
MOZ_ASSERT(showResponse);
|
|
rv = showResponse->Init(aRequestId, responseStatus, u""_ns, nullptr, u""_ns,
|
|
u""_ns, u""_ns);
|
|
rv = RespondPayment(showResponse.get());
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
} else {
|
|
mShowingRequest = request;
|
|
rv = LaunchUIAction(aRequestId,
|
|
IPCPaymentActionRequest::TIPCPaymentShowActionRequest);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
bool PaymentRequestService::IsBasicCardPayment(const nsAString& aRequestId) {
|
|
RefPtr<payments::PaymentRequest> request;
|
|
nsresult rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
nsCOMPtr<nsIArray> methods;
|
|
rv = request->GetPaymentMethods(getter_AddRefs(methods));
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
uint32_t length;
|
|
rv = methods->GetLength(&length);
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
RefPtr<BasicCardService> service = BasicCardService::GetService();
|
|
MOZ_ASSERT(service);
|
|
for (uint32_t index = 0; index < length; ++index) {
|
|
nsCOMPtr<nsIPaymentMethodData> method = do_QueryElementAt(methods, index);
|
|
MOZ_ASSERT(method);
|
|
nsAutoString supportedMethods;
|
|
rv = method->GetSupportedMethods(supportedMethods);
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
if (service->IsBasicCardPayment(supportedMethods)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
} // namespace mozilla::dom
|