Backed out changeset 8238a4eeda86 (bug 1497215) for runing a payment test before the leak detection a=backout
authorCiure Andrei <aciure@mozilla.com>
Tue, 23 Oct 2018 17:10:39 +0300
changeset 490863 0920d2b1122d3e364ab7a49be99788b9596e07b0
parent 490862 cc803b2429d86587fbe6c29fed2e2bfb51f9422e
child 490864 d088f3b8a8058e34f43d9aae909c027b41dd2f11
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersbackout
bugs1497215
milestone65.0a1
backs out8238a4eeda863b0a947afef38dd6f0cc4d7aac47
Backed out changeset 8238a4eeda86 (bug 1497215) for runing a payment test before the leak detection a=backout
browser/components/payments/test/unit/test_response_creation.js
dom/interfaces/payments/nsIPaymentActionResponse.idl
dom/payments/BasicCardPayment.cpp
dom/payments/BasicCardPayment.h
dom/payments/PaymentActionResponse.cpp
dom/payments/PaymentActionResponse.h
dom/payments/PaymentRequest.cpp
dom/payments/PaymentRequest.h
dom/payments/PaymentRequestManager.cpp
dom/payments/PaymentResponse.cpp
dom/payments/PaymentResponse.h
dom/payments/ipc/PPaymentRequest.ipdl
dom/payments/ipc/PaymentRequestParent.cpp
dom/payments/ipc/PaymentRequestParent.h
dom/payments/test/BasiccardChromeScript.js
dom/payments/test/test_basiccard.html
--- a/browser/components/payments/test/unit/test_response_creation.js
+++ b/browser/components/payments/test/unit/test_response_creation.js
@@ -5,39 +5,47 @@
  * destructured arguments properly to the `init` methods. Full testing of the init
  * methods is left to the DOM code.
  */
 
 const DIALOG_WRAPPER_URI = "chrome://payments/content/paymentDialogWrapper.js";
 let dialogGlobal = {};
 Services.scriptloader.loadSubScript(DIALOG_WRAPPER_URI, dialogGlobal);
 
+/**
+ * @param {Object} responseData with properties in the order matching `nsIBasicCardResponseData`
+ *                              init method args.
+ * @returns {string} serialized card data
+ */
+function serializeBasicCardResponseData(responseData) {
+  return [...Object.entries(responseData)].map(array => array.join(":")).join(";") + ";";
+}
+
+
 add_task(async function test_createBasicCardResponseData_basic() {
   let expected = {
     cardholderName: "John Smith",
     cardNumber: "1234567890",
     expiryMonth: "01",
     expiryYear: "2017",
     cardSecurityCode: "0123",
   };
   let actual = dialogGlobal.paymentDialogWrapper.createBasicCardResponseData(expected);
-  Assert.equal(actual.cardholderName, expected.cardholderName, "Check cardholderName");
-  Assert.equal(actual.cardNumber, expected.cardNumber, "Check cardNumber");
-  Assert.equal(actual.expiryMonth, expected.expiryMonth, "Check expiryMonth");
-  Assert.equal(actual.expiryYear, expected.expiryYear, "Check expiryYear");
-  Assert.equal(actual.cardSecurityCode, expected.cardSecurityCode, "Check cardSecurityCode");
+  let expectedSerialized = serializeBasicCardResponseData(expected);
+  Assert.equal(actual.data, expectedSerialized, "Check data");
 });
 
 add_task(async function test_createBasicCardResponseData_minimal() {
   let expected = {
     cardNumber: "1234567890",
   };
   let actual = dialogGlobal.paymentDialogWrapper.createBasicCardResponseData(expected);
-  info(actual.cardNumber);
-  Assert.equal(actual.cardNumber, expected.cardNumber, "Check cardNumber");
+  let expectedSerialized = serializeBasicCardResponseData(expected);
+  info(actual.data);
+  Assert.equal(actual.data, expectedSerialized, "Check data");
 });
 
 add_task(async function test_createBasicCardResponseData_withoutNumber() {
   let data = {
     cardholderName: "John Smith",
     expiryMonth: "01",
     expiryYear: "2017",
     cardSecurityCode: "0123",
@@ -117,11 +125,16 @@ add_task(async function test_createShowR
   for (let [propName, propVal] of Object.entries(actual)) {
     if (typeof(propVal) != "string") {
       continue;
     }
     if (propName == "requestId") {
       Assert.equal(propVal, requestId, `Check ${propName}`);
       continue;
     }
+    if (propName == "data") {
+      Assert.equal(propVal, serializeBasicCardResponseData(cardData), `Check ${propName}`);
+      continue;
+    }
+
     Assert.equal(propVal, responseData[propName], `Check ${propName}`);
   }
 });
--- a/dom/interfaces/payments/nsIPaymentActionResponse.idl
+++ b/dom/interfaces/payments/nsIPaymentActionResponse.idl
@@ -64,44 +64,19 @@ interface nsIGeneralResponseData : nsIPa
  *  given JSObject directly, because PaymentAddress creation in JS code is hard.
  *  To let UI code can create BasicCardResponse easier, nsIBasicCardResponse is
  *  provided for UI by passing the raw data of BasicCardResponse,
  */
 [builtinclass, scriptable, uuid(0d55a5e6-d185-44f0-b992-a8e1321e4bce)]
 interface nsIBasicCardResponseData : nsIPaymentResponseData
 {
   /**
-   *  The cardholder name.
-   */
-  readonly attribute AString cardholderName;
-
-  /**
-   *  The card number.
-   */
-  readonly attribute AString cardNumber;
-
-  /**
-   *  The expiry month.
+   *  The stringified response data.
    */
-  readonly attribute AString expiryMonth;
-
-  /**
-   *  The expiry year.
-   */
-  readonly attribute AString expiryYear;
-
-  /**
-   *  The card security number.
-   */
-  readonly attribute AString cardSecurityCode;
-
-  /**
-   *  The billing address.
-   */
-  readonly attribute nsIPaymentAddress billingAddress;
+  readonly attribute AString data;
 
   /**
    *  The initial method for nsIBasicCardResponseData.
    *  @param aCardholderName   - the cardholder name.
    *  @param aCardNumber       - the card number.
    *  @param aExpiryMonth      - the expiry month.
    *  @param aExpiryYear       - the expiry year.
    *  @param aCardSecurityCode - the card security code.
@@ -203,17 +178,17 @@ interface nsIPaymentShowActionResponse :
   /**
    *  The decided payment method name. i.e. "basic-card".
    */
   readonly attribute AString methodName;
 
   /**
    *  The data needed by the payment method. (it must be serializable)
    */
-  readonly attribute nsIPaymentResponseData data;
+  readonly attribute AString data;
 
   /**
    *  The payer name information.
    */
   readonly attribute AString payerName;
 
   /**
    *  The payer email information.
--- a/dom/payments/BasicCardPayment.cpp
+++ b/dom/payments/BasicCardPayment.cpp
@@ -9,29 +9,127 @@
 #include "mozilla/ClearOnShutdown.h"
 #include "nsArrayUtils.h"
 #include "nsISupportsPrimitives.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsDataHashtable.h"
 
 namespace mozilla {
 namespace dom {
+#ifndef PaymentBasicCardMacros
+#define PaymentBasicCardMacros
+
+#define AMEX NS_LITERAL_STRING("amex")
+#define CARTEBANCAIRE NS_LITERAL_STRING("cartebancaire")
+#define DINERS NS_LITERAL_STRING("diners")
+#define DISCOVER NS_LITERAL_STRING("discover")
+#define JCB NS_LITERAL_STRING("jcb")
+#define MASTERCARD NS_LITERAL_STRING("mastercard")
+#define MIR NS_LITERAL_STRING("mir")
+#define UNIONPAY NS_LITERAL_STRING("unionpay")
+#define VISA NS_LITERAL_STRING("visa")
+
+#define CardholderName NS_LITERAL_STRING("cardholderName")
+#define CardNumber NS_LITERAL_STRING("cardNumber")
+#define ExpiryMonth NS_LITERAL_STRING("expiryMonth")
+#define ExpiryYear NS_LITERAL_STRING("expiryYear")
+#define CardSecurityCode NS_LITERAL_STRING("cardSecurityCode")
+
+#define Country NS_LITERAL_STRING("country")
+#define AddressLine NS_LITERAL_STRING("addressLine")
+#define Region NS_LITERAL_STRING("region")
+#define RegionCode NS_LITERAL_STRING("regionCode")
+#define City NS_LITERAL_STRING("city")
+#define DependentLocality NS_LITERAL_STRING("dependentLocality")
+#define PostalCode NS_LITERAL_STRING("postalCode")
+#define SortingCode NS_LITERAL_STRING("sortingCode")
+#define Organization NS_LITERAL_STRING("organization")
+#define Recipient NS_LITERAL_STRING("recipient")
+#define Phone NS_LITERAL_STRING("phone")
+
+#define PropertySpliter NS_LITERAL_STRING(";")
+#define KeyValueSpliter NS_LITERAL_STRING(":")
+#define AddressLineSpliter NS_LITERAL_STRING("%")
+
+#define EncodeBasicCardProperty(aPropertyName, aPropertyValue, aResult)        \
+  do {                                                                         \
+    if (!(aPropertyValue).IsEmpty()) {                                         \
+      (aResult) += (aPropertyName)                                             \
+                 + KeyValueSpliter                                             \
+                 + (aPropertyValue)                                            \
+                 + PropertySpliter;                                            \
+    }                                                                          \
+  } while(0)
+
+#define EncodeAddressProperty(aAddress, aPropertyName, aResult)                \
+  do {                                                                         \
+    nsAutoString propertyValue;                                                \
+    NS_ENSURE_SUCCESS((aAddress)->Get##aPropertyName(propertyValue),           \
+                                                     NS_ERROR_FAILURE);        \
+    EncodeBasicCardProperty((aPropertyName) ,propertyValue , (aResult));       \
+  } while(0)
+
+#define DecodeBasicCardProperty(aPropertyName, aPropertyValue,                 \
+                                aMatchPropertyName, aResponse)                 \
+  do {                                                                         \
+    if ((aPropertyName).Equals((aMatchPropertyName))) {                        \
+      (aResponse).m##aMatchPropertyName.Construct();                           \
+      (aResponse).m##aMatchPropertyName.Value() = (aPropertyValue);            \
+    }                                                                          \
+  } while(0)
+
+#define DecodeAddressProperty(aPropertyName, aPropertyValue,                   \
+                              aMatchPropertyName, aMatchPropertyValue)         \
+  do {                                                                         \
+    if ((aPropertyName).Equals((aMatchPropertyName))) {                        \
+      (aMatchPropertyValue) = (aPropertyValue);                                \
+    }                                                                          \
+  } while(0)
+
+#endif
+
 namespace {
+
 bool IsValidNetwork(const nsAString& aNetwork)
 {
-  return aNetwork.Equals(NS_LITERAL_STRING("amex")) ||
-         aNetwork.Equals(NS_LITERAL_STRING("cartebancaire")) ||
-         aNetwork.Equals(NS_LITERAL_STRING("diners")) ||
-         aNetwork.Equals(NS_LITERAL_STRING("discover")) ||
-         aNetwork.Equals(NS_LITERAL_STRING("jcb")) ||
-         aNetwork.Equals(NS_LITERAL_STRING("mastercard")) ||
-         aNetwork.Equals(NS_LITERAL_STRING("mir")) ||
-         aNetwork.Equals(NS_LITERAL_STRING("unionpay")) ||
-         aNetwork.Equals(NS_LITERAL_STRING("visa"));
+  return AMEX.Equals(aNetwork) ||
+         CARTEBANCAIRE.Equals(aNetwork) ||
+         DINERS.Equals(aNetwork) ||
+         DISCOVER.Equals(aNetwork) ||
+         JCB.Equals(aNetwork) ||
+         MASTERCARD.Equals(aNetwork) ||
+         MIR.Equals(aNetwork) ||
+         UNIONPAY.Equals(aNetwork) ||
+         VISA.Equals(aNetwork);
 }
+
+bool IsBasicCardKey(const nsAString& aKey)
+{
+  return CardholderName.Equals(aKey) ||
+         CardNumber.Equals(aKey) ||
+         ExpiryMonth.Equals(aKey) ||
+         ExpiryYear.Equals(aKey) ||
+         CardSecurityCode.Equals(aKey);
+}
+
+bool IsAddressKey(const nsAString& aKey)
+{
+  return Country.Equals(aKey) ||
+         AddressLine.Equals(aKey) ||
+         Region.Equals(aKey) ||
+         RegionCode.Equals(aKey) ||
+         City.Equals(aKey) ||
+         DependentLocality.Equals(aKey) ||
+         PostalCode.Equals(aKey) ||
+         SortingCode.Equals(aKey) ||
+         Organization.Equals(aKey) ||
+         Recipient.Equals(aKey) ||
+         Phone.Equals(aKey);
+}
+
 } // end of namespace
 
 
 StaticRefPtr<BasicCardService> gBasicCardService;
 
 already_AddRefed<BasicCardService>
 BasicCardService::GetService()
 {
@@ -120,22 +218,185 @@ BasicCardService::IsValidExpiryYear(cons
           aExpiryYear.CharAt(index) > '9') {
         return false;
       }
     }
   }
   return true;
 }
 
+nsresult
+BasicCardService::EncodeBasicCardData(const nsAString& aCardholderName,
+                                      const nsAString& aCardNumber,
+                                      const nsAString& aExpiryMonth,
+                                      const nsAString& aExpiryYear,
+                                      const nsAString& aCardSecurityCode,
+                                      nsIPaymentAddress* aBillingAddress,
+                                      nsAString& aResult)
+{
+  // aBillingAddress can be nullptr
+  if (aCardNumber.IsEmpty()) {
+    return NS_ERROR_FAILURE;
+  }
+  EncodeBasicCardProperty(CardholderName, aCardholderName, aResult);
+  EncodeBasicCardProperty(CardNumber, aCardNumber, aResult);
+  EncodeBasicCardProperty(ExpiryMonth, aExpiryMonth, aResult);
+  EncodeBasicCardProperty(ExpiryYear, aExpiryYear, aResult);
+  EncodeBasicCardProperty(CardSecurityCode, aCardSecurityCode, aResult);
+  if (!aBillingAddress) {
+    return NS_OK;
+  }
+  EncodeAddressProperty(aBillingAddress, Country, aResult);
+  nsCOMPtr<nsIArray> addressLine;
+  NS_ENSURE_SUCCESS(aBillingAddress->GetAddressLine(getter_AddRefs(addressLine)),
+                                                    NS_ERROR_FAILURE);
+  uint32_t length;
+  nsAutoString addressLineString;
+  NS_ENSURE_SUCCESS(addressLine->GetLength(&length), NS_ERROR_FAILURE);
+  for (uint32_t index = 0; index < length; ++index) {
+    nsCOMPtr<nsISupportsString> address = do_QueryElementAt(addressLine, index);
+    MOZ_ASSERT(address);
+    nsAutoString addressString;
+    NS_ENSURE_SUCCESS(address->GetData(addressString), NS_ERROR_FAILURE);
+    addressLineString += addressString + AddressLineSpliter;
+  }
+  EncodeBasicCardProperty(AddressLine ,addressLineString , aResult);
+  EncodeAddressProperty(aBillingAddress, Region, aResult);
+  EncodeAddressProperty(aBillingAddress, RegionCode, aResult);
+  EncodeAddressProperty(aBillingAddress, City, aResult);
+  EncodeAddressProperty(aBillingAddress, DependentLocality, aResult);
+  EncodeAddressProperty(aBillingAddress, PostalCode, aResult);
+  EncodeAddressProperty(aBillingAddress, SortingCode, aResult);
+  EncodeAddressProperty(aBillingAddress, Organization, aResult);
+  EncodeAddressProperty(aBillingAddress, Recipient, aResult);
+  EncodeAddressProperty(aBillingAddress, Phone, aResult);
+  return NS_OK;
+}
+
+nsresult
+BasicCardService::DecodeBasicCardData(const nsAString& aData,
+                                      nsPIDOMWindowInner* aWindow,
+                                      BasicCardResponse& aResponse)
+{
+  // aWindow can be nullptr
+  bool isBillingAddressPassed = false;
+  nsTArray<nsString> addressLine;
+  nsAutoString country;
+  nsAutoString region;
+  nsAutoString regionCode;
+  nsAutoString city;
+  nsAutoString dependentLocality;
+  nsAutoString postalCode;
+  nsAutoString sortingCode;
+  nsAutoString organization;
+  nsAutoString recipient;
+  nsAutoString phone;
+
+  nsCharSeparatedTokenizer propertyTokenizer(aData, PropertySpliter.CharAt(0));
+  while (propertyTokenizer.hasMoreTokens()) {
+    nsDependentSubstring property = propertyTokenizer.nextToken();
+    nsCharSeparatedTokenizer keyValueTokenizer(property, KeyValueSpliter.CharAt(0));
+    MOZ_ASSERT(keyValueTokenizer.hasMoreTokens());
+    nsDependentSubstring key = keyValueTokenizer.nextToken();
+    nsDependentSubstring value = keyValueTokenizer.nextToken();
+    if (IsAddressKey(key) && !isBillingAddressPassed) {
+      isBillingAddressPassed = true;
+    }
+    if (!IsAddressKey(key) && !IsBasicCardKey(key)) {
+      return NS_ERROR_FAILURE;
+    }
+
+    if (key.Equals(CardNumber)) {
+      aResponse.mCardNumber = (value);
+    }
+
+    DecodeBasicCardProperty(key, value, CardholderName, aResponse);
+    DecodeBasicCardProperty(key, value, ExpiryMonth, aResponse);
+    DecodeBasicCardProperty(key, value, ExpiryYear, aResponse);
+    DecodeBasicCardProperty(key, value, CardSecurityCode, aResponse);
+
+    DecodeAddressProperty(key, value, Country, country);
+    DecodeAddressProperty(key, value, Region, region);
+    DecodeAddressProperty(key, value, RegionCode, regionCode);
+    DecodeAddressProperty(key, value, City, city);
+    DecodeAddressProperty(key, value, DependentLocality, dependentLocality);
+    DecodeAddressProperty(key, value, PostalCode, postalCode);
+    DecodeAddressProperty(key, value, SortingCode, sortingCode);
+    DecodeAddressProperty(key, value, Organization, organization);
+    DecodeAddressProperty(key, value, Recipient, recipient);
+    DecodeAddressProperty(key, value, Phone, phone);
+
+    if ((key).Equals(AddressLine)) {
+      nsCharSeparatedTokenizer addressTokenizer(value, AddressLineSpliter.CharAt(0));
+      while (addressTokenizer.hasMoreTokens()) {
+        addressLine.AppendElement(addressTokenizer.nextToken());
+      }
+    }
+  }
+  if (isBillingAddressPassed) {
+    aResponse.mBillingAddress.Construct();
+    aResponse.mBillingAddress.Value() = new PaymentAddress(aWindow,
+                                                           country,
+                                                           addressLine,
+                                                           region,
+                                                           regionCode,
+                                                           city,
+                                                           dependentLocality,
+                                                           postalCode,
+                                                           sortingCode,
+                                                           organization,
+                                                           recipient,
+                                                           phone);
+  }
+  return NS_OK;
+}
+
 bool
 BasicCardService::IsValidBasicCardErrors(JSContext* aCx,
                                          JSObject* aData)
 {
   if (!aData) {
     return true;
   }
   JS::RootedValue data(aCx, JS::ObjectValue(*aData));
 
   BasicCardErrors bcError;
   return !bcError.Init(aCx, data);
 }
+
+#ifdef PaymentBasicCardMacros
+#undef PaymentBasicCardMacros
+#undef EncodeBasicCardProperty
+#undef EncodeAddressProperty
+#undef DecodeBasicCardProperty
+#undef DecodeAddressProperty
+#undef AMEX
+#undef CARTEBANCAIRE
+#undef DINERS
+#undef DISCOVER
+#undef JCB
+#undef MASTERCARD
+#undef MIR
+#undef UNIONPAY
+#undef VISA
+#undef CardholderName
+#undef CardNumber
+#undef ExpiryMonth
+#undef ExpiryYear
+#undef CardSecurityCode
+#undef Country
+#undef AddressLine
+#undef Region
+#undef RegionCode
+#undef City
+#undef DependentLocality
+#undef PostalCode
+#undef SortingCode
+#undef Organization
+#undef Recipient
+#undef Phone
+#undef PropertySpliter
+#undef KeyValueSpliter
+#undef AddressLineSpliter
+#endif
+
 } // end of namespace dom
 } // end of namespace mozilla
--- a/dom/payments/BasicCardPayment.h
+++ b/dom/payments/BasicCardPayment.h
@@ -22,16 +22,32 @@ public:
 
   static already_AddRefed<BasicCardService> GetService();
 
   bool IsBasicCardPayment(const nsAString& aSupportedMethods);
   bool IsValidBasicCardRequest(JSContext* aCx, JSObject* aData, nsAString& aErrorMsg);
   bool IsValidBasicCardErrors(JSContext* aCx, JSObject* aData);
   bool IsValidExpiryMonth(const nsAString& aExpiryMonth);
   bool IsValidExpiryYear(const nsAString& aExpiryYear);
+/*
+  To let BasicCardResponse using the same data type with non-BasicCard response
+  in IPC transferring, following two methods is used to Encode/Decode the raw
+  data of BasicCardResponse.
+*/
+  nsresult EncodeBasicCardData(const nsAString& aCardholderName,
+                               const nsAString& aCardNumber,
+                               const nsAString& aExpiryMonth,
+                               const nsAString& aExpiryYear,
+                               const nsAString& aCardSecurityCode,
+                               nsIPaymentAddress* aBillingAddress,
+                               nsAString& aResult);
+
+  nsresult DecodeBasicCardData(const nsAString& aData,
+                               nsPIDOMWindowInner* aWindow,
+                               BasicCardResponse& aResponse);
 private:
   BasicCardService() = default;
   ~BasicCardService() = default;
 };
 
 } // end of namespace dom
 } // end of namespace mozilla
 
--- a/dom/payments/PaymentActionResponse.cpp
+++ b/dom/payments/PaymentActionResponse.cpp
@@ -1,16 +1,17 @@
 /* -*- 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 "PaymentActionResponse.h"
 #include "PaymentRequestUtils.h"
+#include "BasicCardPayment.h"
 
 namespace mozilla {
 namespace dom {
 
 /* PaymentResponseData */
 
 NS_IMPL_ISUPPORTS(PaymentResponseData, nsIPaymentResponseData)
 
@@ -72,57 +73,19 @@ NS_IMPL_ISUPPORTS_INHERITED(BasicCardRes
                             nsIBasicCardResponseData)
 
 BasicCardResponseData::BasicCardResponseData()
 {
   Init(nsIPaymentResponseData::BASICCARD_RESPONSE);
 }
 
 NS_IMETHODIMP
-BasicCardResponseData::GetCardholderName(nsAString& aCardholderName)
-{
-  aCardholderName = mCardholderName;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasicCardResponseData::GetCardNumber(nsAString& aCardNumber)
-{
-  aCardNumber = mCardNumber;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasicCardResponseData::GetExpiryMonth(nsAString& aExpiryMonth)
+BasicCardResponseData::GetData(nsAString& aData)
 {
-  aExpiryMonth = mExpiryMonth;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasicCardResponseData::GetExpiryYear(nsAString& aExpiryYear)
-{
-  aExpiryYear = mExpiryYear;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasicCardResponseData::GetCardSecurityCode(nsAString& aCardSecurityCode)
-{
-  aCardSecurityCode = mCardSecurityCode;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-BasicCardResponseData::GetBillingAddress(nsIPaymentAddress** aBillingAddress)
-{
-  NS_ENSURE_ARG_POINTER(aBillingAddress);
-  nsCOMPtr<nsIPaymentAddress> address;
-  address = mBillingAddress;
-  address.forget(aBillingAddress);
+  aData = mData;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BasicCardResponseData::InitData(const nsAString& aCardholderName,
                                 const nsAString& aCardNumber,
                                 const nsAString& aExpiryMonth,
                                 const nsAString& aExpiryYear,
@@ -139,24 +102,26 @@ BasicCardResponseData::InitData(const ns
 
   if (!service->IsValidExpiryMonth(aExpiryMonth)) {
     return NS_ERROR_FAILURE;
   }
 
   if (!service->IsValidExpiryYear(aExpiryYear)) {
     return NS_ERROR_FAILURE;
   }
-
-  mCardholderName = aCardholderName;
-  mCardNumber = aCardNumber;
-  mExpiryMonth = aExpiryMonth;
-  mExpiryYear = aExpiryYear;
-  mCardSecurityCode = aCardSecurityCode;
-  mBillingAddress = aBillingAddress;
-
+  nsresult rv = service->EncodeBasicCardData(aCardholderName,
+                                             aCardNumber,
+                                             aExpiryMonth,
+                                             aExpiryYear,
+                                             aCardSecurityCode,
+                                             aBillingAddress,
+                                             mData);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
   return NS_OK;
 }
 
 /* PaymentActionResponse */
 
 NS_IMPL_ISUPPORTS(PaymentActionResponse,
                   nsIPaymentActionResponse)
 
@@ -232,21 +197,19 @@ PaymentShowActionResponse::GetAcceptStat
 NS_IMETHODIMP
 PaymentShowActionResponse::GetMethodName(nsAString& aMethodName)
 {
   aMethodName = mMethodName;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-PaymentShowActionResponse::GetData(nsIPaymentResponseData** aData)
+PaymentShowActionResponse::GetData(nsAString& aData)
 {
-  NS_ENSURE_ARG_POINTER(aData);
-  nsCOMPtr<nsIPaymentResponseData> data = mData;
-  data.forget(aData);
+  aData = mData;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PaymentShowActionResponse::GetPayerName(nsAString& aPayerName)
 {
   aPayerName = mPayerName;
   return NS_OK;
@@ -290,30 +253,38 @@ PaymentShowActionResponse::Init(const ns
   if (aAcceptStatus == nsIPaymentActionResponse::PAYMENT_ACCEPTED) {
     uint32_t responseType;
     NS_ENSURE_SUCCESS(aData->GetType(&responseType), NS_ERROR_FAILURE);
     switch (responseType) {
       case nsIPaymentResponseData::GENERAL_RESPONSE: {
         if (isBasicCardPayment) {
           return NS_ERROR_FAILURE;
         }
+        nsCOMPtr<nsIGeneralResponseData> data = do_QueryInterface(aData);
+        MOZ_ASSERT(data);
+        NS_ENSURE_SUCCESS(data->GetData(mData), NS_ERROR_FAILURE);
         break;
       }
       case nsIPaymentResponseData::BASICCARD_RESPONSE: {
         if (!isBasicCardPayment) {
           return NS_ERROR_FAILURE;
         }
+        nsCOMPtr<nsIBasicCardResponseData> data = do_QueryInterface(aData);
+        MOZ_ASSERT(data);
+        NS_ENSURE_SUCCESS(data->GetData(mData), NS_ERROR_FAILURE);
         break;
       }
       default: {
         return NS_ERROR_FAILURE;
       }
     }
+    if (mData.IsEmpty()) {
+      return NS_ERROR_FAILURE;
+    }
   }
-  mData = aData;
   mPayerName = aPayerName;
   mPayerEmail = aPayerEmail;
   mPayerPhone = aPayerPhone;
   return NS_OK;
 }
 
 /* PaymentAbortActionResponse */
 
--- a/dom/payments/PaymentActionResponse.h
+++ b/dom/payments/PaymentActionResponse.h
@@ -52,21 +52,17 @@ public:
   NS_FORWARD_NSIPAYMENTRESPONSEDATA(PaymentResponseData::)
   NS_DECL_NSIBASICCARDRESPONSEDATA
 
   BasicCardResponseData();
 
 private:
   ~BasicCardResponseData() = default;
 
-  nsString mCardholderName;
-  nsString mCardNumber;
-  nsString mExpiryMonth;
-  nsString mExpiryYear;
-  nsString mCardSecurityCode;
+  nsString mData;
   nsCOMPtr<nsIPaymentAddress> mBillingAddress;
 };
 
 class PaymentActionResponse : public nsIPaymentActionResponse
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPAYMENTACTIONRESPONSE
@@ -106,17 +102,17 @@ public:
 
   PaymentShowActionResponse();
 
 private:
   ~PaymentShowActionResponse() = default;
 
   uint32_t mAcceptStatus;
   nsString mMethodName;
-  nsCOMPtr<nsIPaymentResponseData> mData;
+  nsString mData;
   nsString mPayerName;
   nsString mPayerEmail;
   nsString mPayerPhone;
 };
 
 class PaymentAbortActionResponse final : public nsIPaymentAbortActionResponse
                                        , public PaymentActionResponse
 {
--- a/dom/payments/PaymentRequest.cpp
+++ b/dom/payments/PaymentRequest.cpp
@@ -792,17 +792,17 @@ PaymentRequest::RejectShowPayment(nsresu
     mAcceptPromise->MaybeReject(aRejectReason);
   }
   mState = eClosed;
   mAcceptPromise = nullptr;
 }
 
 void
 PaymentRequest::RespondShowPayment(const nsAString& aMethodName,
-                                   const ResponseData& aDetails,
+                                   const nsAString& aDetails,
                                    const nsAString& aPayerName,
                                    const nsAString& aPayerEmail,
                                    const nsAString& aPayerPhone,
                                    nsresult aRv)
 {
   MOZ_ASSERT(mAcceptPromise || mResponse);
   MOZ_ASSERT(mState == eInteractive);
 
@@ -883,17 +883,17 @@ PaymentRequest::RespondAbortPayment(bool
   //   => Reject |mAcceptPromise| and reset |mUpdateError| to complete
   //      the action, regardless of |aSuccess|.
   //
   // - Otherwise, we are handling |Abort| method call from merchant.
   //   => Resolve/Reject |mAbortPromise| based on |aSuccess|.
   if (NS_FAILED(mUpdateError)) {
     // Respond show with mUpdateError, set mUpdating to false.
     mUpdating = false;
-    RespondShowPayment(EmptyString(), ResponseData(), EmptyString(),
+    RespondShowPayment(EmptyString(), EmptyString(), EmptyString(),
                        EmptyString(), EmptyString(), mUpdateError);
     mUpdateError = NS_OK;
     return;
   }
 
   MOZ_ASSERT(mAbortPromise);
   MOZ_ASSERT(mState == eInteractive);
 
--- a/dom/payments/PaymentRequest.h
+++ b/dom/payments/PaymentRequest.h
@@ -18,17 +18,16 @@
 
 namespace mozilla {
 namespace dom {
 
 class EventHandlerNonNull;
 class PaymentAddress;
 class PaymentRequestChild;
 class PaymentResponse;
-class ResponseData;
 
 class PaymentRequest final
   : public DOMEventTargetHelper
   , public PromiseNativeHandler
   , public nsIDocumentActivity
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
@@ -92,17 +91,17 @@ public:
 
   already_AddRefed<Promise> CanMakePayment(ErrorResult& aRv);
   void RespondCanMakePayment(bool aResult);
 
   already_AddRefed<Promise> Show(
     const Optional<OwningNonNull<Promise>>& detailsPromise,
     ErrorResult& aRv);
   void RespondShowPayment(const nsAString& aMethodName,
-                          const ResponseData& aDetails,
+                          const nsAString& aDetails,
                           const nsAString& aPayerName,
                           const nsAString& aPayerEmail,
                           const nsAString& aPayerPhone,
                           nsresult aRv);
   void RejectShowPayment(nsresult aRejectReason);
   void RespondComplete();
 
   already_AddRefed<Promise> Abort(ErrorResult& aRv);
--- a/dom/payments/PaymentRequestManager.cpp
+++ b/dom/payments/PaymentRequestManager.cpp
@@ -244,84 +244,16 @@ ConvertOptions(const PaymentOptions& aOp
       PaymentShippingTypeValues::strings[shippingTypeIndex].value);
   }
   aIPCOption = IPCPaymentOptions(aOptions.mRequestPayerName,
                                  aOptions.mRequestPayerEmail,
                                  aOptions.mRequestPayerPhone,
                                  aOptions.mRequestShipping,
                                  shippingType);
 }
-
-nsresult
-ConvertResponseData(nsPIDOMWindowInner* aWindow,
-                    const IPCPaymentResponseData& aIPCResponseData,
-                    ResponseData& aResponseData)
-{
-  NS_ENSURE_ARG_POINTER(aWindow);
-  switch(aIPCResponseData.type()) {
-    case IPCPaymentResponseData::TIPCGeneralResponse: {
-      const IPCGeneralResponse& rawData = aIPCResponseData;
-      aResponseData.Init(rawData.data());
-      break;
-    }
-    case IPCPaymentResponseData::TIPCBasicCardResponse: {
-      const IPCBasicCardResponse& rawData = aIPCResponseData;
-      BasicCardResponse basicCardResponse;
-      if (!rawData.cardholderName().IsEmpty()) {
-        basicCardResponse.mCardholderName.Construct();
-        basicCardResponse.mCardholderName.Value() = rawData.cardholderName();
-      }
-      basicCardResponse.mCardNumber = rawData.cardNumber();
-      if (!rawData.expiryMonth().IsEmpty()) {
-        basicCardResponse.mExpiryMonth.Construct();
-        basicCardResponse.mExpiryMonth.Value() = rawData.expiryMonth();
-      }
-      if (!rawData.expiryYear().IsEmpty()) {
-        basicCardResponse.mExpiryYear.Construct();
-        basicCardResponse.mExpiryYear.Value() = rawData.expiryYear();
-      }
-      if (!rawData.cardSecurityCode().IsEmpty()) {
-        basicCardResponse.mCardSecurityCode.Construct();
-        basicCardResponse.mCardSecurityCode.Value() = rawData.cardSecurityCode();
-      }
-      if (!rawData.billingAddress().country().IsEmpty() ||
-          !rawData.billingAddress().addressLine().IsEmpty() ||
-          !rawData.billingAddress().region().IsEmpty() ||
-          !rawData.billingAddress().regionCode().IsEmpty() ||
-          !rawData.billingAddress().city().IsEmpty() ||
-          !rawData.billingAddress().dependentLocality().IsEmpty() ||
-          !rawData.billingAddress().postalCode().IsEmpty() ||
-          !rawData.billingAddress().sortingCode().IsEmpty() ||
-          !rawData.billingAddress().organization().IsEmpty() ||
-          !rawData.billingAddress().recipient().IsEmpty() ||
-          !rawData.billingAddress().phone().IsEmpty()) {
-        basicCardResponse.mBillingAddress.Construct();
-        basicCardResponse.mBillingAddress.Value() =
-          new PaymentAddress(aWindow,
-                             rawData.billingAddress().country(),
-                             rawData.billingAddress().addressLine(),
-                             rawData.billingAddress().region(),
-                             rawData.billingAddress().regionCode(),
-                             rawData.billingAddress().city(),
-                             rawData.billingAddress().dependentLocality(),
-                             rawData.billingAddress().postalCode(),
-                             rawData.billingAddress().sortingCode(),
-                             rawData.billingAddress().organization(),
-                             rawData.billingAddress().recipient(),
-                             rawData.billingAddress().phone());
-      }
-      aResponseData.Init(basicCardResponse);
-      break;
-    }
-    default: {
-      return NS_ERROR_FAILURE;
-    }
-  }
-  return NS_OK;
-}
 } // end of namespace
 
 /* PaymentRequestManager */
 
 StaticRefPtr<PaymentRequestManager> gPaymentManager;
 
 PaymentRequestChild*
 PaymentRequestManager::GetPaymentChild(PaymentRequest* aRequest)
@@ -652,41 +584,36 @@ PaymentRequestManager::RespondPayment(Pa
       const IPCPaymentCanMakeActionResponse& response = aResponse;
       aRequest->RespondCanMakePayment(response.result());
       NotifyRequestDone(aRequest);
       break;
     }
     case IPCPaymentActionResponse::TIPCPaymentShowActionResponse: {
       const IPCPaymentShowActionResponse& response = aResponse;
       nsresult rejectedReason = NS_ERROR_DOM_ABORT_ERR;
-      ResponseData responseData;
       switch (response.status()) {
         case nsIPaymentActionResponse::PAYMENT_ACCEPTED: {
           rejectedReason = NS_OK;
-          NS_ENSURE_SUCCESS(ConvertResponseData(aRequest->GetOwner(),
-                                                response.data(),
-                                                responseData),
-                            NS_ERROR_FAILURE);
           break;
         }
         case nsIPaymentActionResponse::PAYMENT_REJECTED: {
           rejectedReason = NS_ERROR_DOM_ABORT_ERR;
           break;
         }
         case nsIPaymentActionResponse::PAYMENT_NOTSUPPORTED: {
           rejectedReason = NS_ERROR_DOM_NOT_SUPPORTED_ERR;
           break;
         }
         default: {
           rejectedReason = NS_ERROR_UNEXPECTED;
           break;
         }
       }
       aRequest->RespondShowPayment(response.methodName(),
-                                   responseData,
+                                   response.data(),
                                    response.payerName(),
                                    response.payerEmail(),
                                    response.payerPhone(),
                                    rejectedReason);
       if (NS_FAILED(rejectedReason)) {
         NotifyRequestDone(aRequest);
       }
       break;
--- a/dom/payments/PaymentResponse.cpp
+++ b/dom/payments/PaymentResponse.cpp
@@ -11,60 +11,16 @@
 #include "BasicCardPayment.h"
 #include "PaymentAddress.h"
 #include "PaymentRequestUtils.h"
 #include "mozilla/EventStateManager.h"
 
 namespace mozilla {
 namespace dom {
 
-ResponseData::ResponseData()
-  : mType(ResponseData::UNKNOWN)
-{
-}
-
-void
-ResponseData::GetData(JSContext* aCx, JS::MutableHandle<JSObject*> aRetVal) const
-{
-  switch (mType) {
-    case ResponseData::GENERAL_RESPONSE : {
-      DeserializeToJSObject(mGeneralResponse, aCx, aRetVal);
-      break;
-    }
-    case ResponseData::BASICCARD_RESPONSE : {
-      MOZ_ASSERT(aCx);
-      JS::RootedValue value(aCx);
-      if (NS_WARN_IF(!mBasicCardResponse.ToObjectInternal(aCx, &value))) {
-        return;
-      }
-      aRetVal.set(&value.toObject());
-      break;
-    }
-    default : {
-      break;
-    }
-  }
-}
-
-void
-ResponseData::Init(const nsString& aGeneralResponse)
-{
-  mType = ResponseData::GENERAL_RESPONSE;
-  mGeneralResponse = aGeneralResponse;
-  mBasicCardResponse = BasicCardResponse();
-}
-
-void
-ResponseData::Init(const BasicCardResponse& aBasicCardResponse)
-{
-  mType = ResponseData::BASICCARD_RESPONSE;
-  mBasicCardResponse = aBasicCardResponse;
-  mGeneralResponse = EmptyString();
-}
-
 NS_IMPL_CYCLE_COLLECTION_CLASS(PaymentResponse)
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PaymentResponse,
                                                DOMEventTargetHelper)
   // Don't need NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER because
   // DOMEventTargetHelper does it for us.
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
@@ -90,17 +46,17 @@ NS_IMPL_ADDREF_INHERITED(PaymentResponse
 NS_IMPL_RELEASE_INHERITED(PaymentResponse, DOMEventTargetHelper)
 
 PaymentResponse::PaymentResponse(nsPIDOMWindowInner* aWindow,
                                  PaymentRequest* aRequest,
                                  const nsAString& aRequestId,
                                  const nsAString& aMethodName,
                                  const nsAString& aShippingOption,
                                  PaymentAddress* aShippingAddress,
-                                 const ResponseData& aDetails,
+                                 const nsAString& aDetails,
                                  const nsAString& aPayerName,
                                  const nsAString& aPayerEmail,
                                  const nsAString& aPayerPhone)
   : DOMEventTargetHelper(aWindow)
   , mCompleteCalled(false)
   , mRequest(aRequest)
   , mRequestId(aRequestId)
   , mMethodName(aMethodName)
@@ -140,17 +96,34 @@ PaymentResponse::GetMethodName(nsString&
 {
   aRetVal = mMethodName;
 }
 
 void
 PaymentResponse::GetDetails(JSContext* aCx,
                             JS::MutableHandle<JSObject*> aRetVal) const
 {
-  mDetails.GetData(aCx, aRetVal);
+  RefPtr<BasicCardService> service = BasicCardService::GetService();
+  MOZ_ASSERT(service);
+  if (!service->IsBasicCardPayment(mMethodName)) {
+    DeserializeToJSObject(mDetails, aCx, aRetVal);
+  } else {
+    BasicCardResponse response;
+    nsresult rv = service->DecodeBasicCardData(mDetails, GetOwner(), response);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return;
+    }
+
+    MOZ_ASSERT(aCx);
+    JS::RootedValue value(aCx);
+    if (NS_WARN_IF(!response.ToObjectInternal(aCx, &value))) {
+      return;
+    }
+    aRetVal.set(&value.toObject());
+  }
 }
 
 void
 PaymentResponse::GetShippingOption(nsString& aRetVal) const
 {
   aRetVal = mShippingOption;
 }
 
@@ -297,17 +270,17 @@ PaymentResponse::Retry(JSContext* aCx,
   mRetryPromise = promise;
   return promise.forget();
 }
 
 void
 PaymentResponse::RespondRetry(const nsAString& aMethodName,
                               const nsAString& aShippingOption,
                               PaymentAddress* aShippingAddress,
-                              const ResponseData& aDetails,
+                              const nsAString& aDetails,
                               const nsAString& aPayerName,
                               const nsAString& aPayerEmail,
                               const nsAString& aPayerPhone)
 {
   mMethodName = aMethodName;
   mShippingOption = aShippingOption;
   mShippingAddress = aShippingAddress;
   mDetails = aDetails;
--- a/dom/payments/PaymentResponse.h
+++ b/dom/payments/PaymentResponse.h
@@ -3,52 +3,27 @@
 /* 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/. */
 
 #ifndef mozilla_dom_PaymentResponse_h
 #define mozilla_dom_PaymentResponse_h
 
 #include "mozilla/DOMEventTargetHelper.h"
-#include "mozilla/dom/BasicCardPaymentBinding.h"
 #include "mozilla/dom/PaymentResponseBinding.h" // PaymentComplete
 #include "nsPIDOMWindow.h"
 #include "nsITimer.h"
 
 namespace mozilla {
 namespace dom {
 
 class PaymentAddress;
 class PaymentRequest;
 class Promise;
 
-class ResponseData final
-{
-public:
-  enum TYPE {
-    UNKNOWN = 0,
-    GENERAL_RESPONSE,
-    BASICCARD_RESPONSE,
-  };
-
-  ResponseData();
-
-  ~ResponseData() = default;
-
-  const TYPE& GetType() const { return mType; }
-  void GetData(JSContext* aCx, JS::MutableHandle<JSObject*> aRetVal) const;
-  void Init(const nsString& aGeneralResponse);
-  void Init(const BasicCardResponse& aBasicCardResponse);
-
-private:
-  TYPE mType;
-  nsString mGeneralResponse;
-  BasicCardResponse mBasicCardResponse;
-};
-
 class PaymentResponse final
   : public DOMEventTargetHelper
   , public nsITimerCallback
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(PaymentResponse,
@@ -57,17 +32,17 @@ public:
   NS_IMETHOD Notify(nsITimer* aTimer) override;
 
   PaymentResponse(nsPIDOMWindowInner* aWindow,
                   PaymentRequest* aRequest,
                   const nsAString& aRequestId,
                   const nsAString& aMethodName,
                   const nsAString& aShippingOption,
                   PaymentAddress* aShippingAddress,
-                  const ResponseData& aDetails,
+                  const nsAString& aDetails,
                   const nsAString& aPayerName,
                   const nsAString& aPayerEmail,
                   const nsAString& aPayerPhone);
 
   virtual JSObject* WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aGivenProto) override;
 
   void GetRequestId(nsString& aRetVal) const;
@@ -100,17 +75,17 @@ public:
 
   already_AddRefed<Promise> Retry(JSContext* aCx,
                                   const PaymentValidationErrors& errorField,
                                   ErrorResult& aRv);
 
   void RespondRetry(const nsAString& aMethodName,
                     const nsAString& aShippingOption,
                     PaymentAddress* aShippingAddress,
-                    const ResponseData& aDetails,
+                    const nsAString& aDetails,
                     const nsAString& aPayerName,
                     const nsAString& aPayerEmail,
                     const nsAString& aPayerPhone);
   void RejectRetry(nsresult aRejectReason);
 
 protected:
   ~PaymentResponse();
 
@@ -123,17 +98,17 @@ protected:
 
   nsresult DispatchUpdateEvent(const nsAString& aType);
 
 private:
   bool mCompleteCalled;
   PaymentRequest* mRequest;
   nsString mRequestId;
   nsString mMethodName;
-  ResponseData mDetails;
+  nsString mDetails;
   nsString mShippingOption;
   nsString mPayerName;
   nsString mPayerEmail;
   nsString mPayerPhone;
   RefPtr<PaymentAddress> mShippingAddress;
   // Promise for "PaymentResponse::Complete"
   RefPtr<Promise> mPromise;
   // Timer for timing out if the page doesn't call
--- a/dom/payments/ipc/PPaymentRequest.ipdl
+++ b/dom/payments/ipc/PPaymentRequest.ipdl
@@ -133,58 +133,22 @@ union IPCPaymentActionRequest
 };
 
 struct IPCPaymentCanMakeActionResponse
 {
   nsString requestId;
   bool result;
 };
 
-struct IPCPaymentAddress
-{
-  nsString country;
-  nsString[] addressLine;
-  nsString region;
-  nsString regionCode;
-  nsString city;
-  nsString dependentLocality;
-  nsString postalCode;
-  nsString sortingCode;
-  nsString organization;
-  nsString recipient;
-  nsString phone;
-};
-
-struct IPCGeneralResponse
-{
-  nsString data;
-};
-
-struct IPCBasicCardResponse
-{
-  nsString cardholderName;
-  nsString cardNumber;
-  nsString expiryMonth;
-  nsString expiryYear;
-  nsString cardSecurityCode;
-  IPCPaymentAddress billingAddress;
-};
-
-union IPCPaymentResponseData
-{
-  IPCGeneralResponse;
-  IPCBasicCardResponse;
-};
-
 struct IPCPaymentShowActionResponse
 {
   nsString requestId;
   uint32_t status;
   nsString methodName;
-  IPCPaymentResponseData data;
+  nsString data;
   nsString payerName;
   nsString payerEmail;
   nsString payerPhone;
 };
 
 struct IPCPaymentAbortActionResponse
 {
   nsString requestId;
@@ -200,16 +164,31 @@ struct IPCPaymentCompleteActionResponse
 union IPCPaymentActionResponse
 {
   IPCPaymentCanMakeActionResponse;
   IPCPaymentShowActionResponse;
   IPCPaymentAbortActionResponse;
   IPCPaymentCompleteActionResponse;
 };
 
+struct IPCPaymentAddress
+{
+  nsString country;
+  nsString[] addressLine;
+  nsString region;
+  nsString regionCode;
+  nsString city;
+  nsString dependentLocality;
+  nsString postalCode;
+  nsString sortingCode;
+  nsString organization;
+  nsString recipient;
+  nsString phone;
+};
+
 sync protocol PPaymentRequest
 {
   manager PBrowser;
 
 parent:
   async __delete__();
 
   async RequestPayment(IPCPaymentActionRequest aAction);
--- a/dom/payments/ipc/PaymentRequestParent.cpp
+++ b/dom/payments/ipc/PaymentRequestParent.cpp
@@ -133,37 +133,28 @@ PaymentRequestParent::RespondPayment(nsI
     case nsIPaymentActionResponse::SHOW_ACTION: {
       nsCOMPtr<nsIPaymentShowActionResponse> response =
         do_QueryInterface(aResponse);
       MOZ_ASSERT(response);
       uint32_t acceptStatus;
       NS_ENSURE_SUCCESS(response->GetAcceptStatus(&acceptStatus), NS_ERROR_FAILURE);
       nsAutoString methodName;
       NS_ENSURE_SUCCESS(response->GetMethodName(methodName), NS_ERROR_FAILURE);
-      IPCPaymentResponseData ipcData;
-      if (acceptStatus == nsIPaymentActionResponse::PAYMENT_ACCEPTED) {
-        nsCOMPtr<nsIPaymentResponseData> data;
-        NS_ENSURE_SUCCESS(response->GetData(getter_AddRefs(data)),
-                          NS_ERROR_FAILURE);
-        MOZ_ASSERT(data);
-        NS_ENSURE_SUCCESS(SerializeResponseData(ipcData, data), NS_ERROR_FAILURE);
-      } else {
-        ipcData = IPCGeneralResponse();
-      }
-
+      nsAutoString data;
+      NS_ENSURE_SUCCESS(response->GetData(data), NS_ERROR_FAILURE);
       nsAutoString payerName;
       NS_ENSURE_SUCCESS(response->GetPayerName(payerName), NS_ERROR_FAILURE);
       nsAutoString payerEmail;
       NS_ENSURE_SUCCESS(response->GetPayerEmail(payerEmail), NS_ERROR_FAILURE);
       nsAutoString payerPhone;
       NS_ENSURE_SUCCESS(response->GetPayerPhone(payerPhone), NS_ERROR_FAILURE);
       IPCPaymentShowActionResponse actionResponse(requestId,
                                                   acceptStatus,
                                                   methodName,
-                                                  ipcData,
+                                                  data,
                                                   payerName,
                                                   payerEmail,
                                                   payerPhone);
       if (!SendRespondPayment(actionResponse)) {
         return NS_ERROR_FAILURE;
       }
       break;
     }
@@ -213,21 +204,77 @@ PaymentRequestParent::ChangeShippingAddr
     {
       self->ChangeShippingAddress(requestId, address);
     });
     return NS_DispatchToMainThread(r);
   }
   if (!mActorAlive) {
     return NS_ERROR_FAILURE;
   }
+  nsAutoString country;
+  nsresult rv = aAddress->GetCountry(country);
+  NS_ENSURE_SUCCESS(rv, rv);
 
-  IPCPaymentAddress ipcAddress;
-  nsresult rv = SerializeAddress(ipcAddress, aAddress);
+  nsCOMPtr<nsIArray> iaddressLine;
+  rv = aAddress->GetAddressLine(getter_AddRefs(iaddressLine));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAutoString region;
+  rv = aAddress->GetRegion(region);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAutoString regionCode;
+  rv = aAddress->GetRegionCode(regionCode);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAutoString city;
+  rv = aAddress->GetCity(city);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAutoString dependentLocality;
+  rv = aAddress->GetDependentLocality(dependentLocality);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAutoString postalCode;
+  rv = aAddress->GetPostalCode(postalCode);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAutoString sortingCode;
+  rv = aAddress->GetSortingCode(sortingCode);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  nsAutoString organization;
+  rv = aAddress->GetOrganization(organization);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAutoString recipient;
+  rv = aAddress->GetRecipient(recipient);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAutoString phone;
+  rv = aAddress->GetPhone(phone);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsTArray<nsString> addressLine;
+  uint32_t length;
+  rv = iaddressLine->GetLength(&length);
+  NS_ENSURE_SUCCESS(rv, rv);
+  for (uint32_t index = 0; index < length; ++index) {
+    nsCOMPtr<nsISupportsString> iaddress = do_QueryElementAt(iaddressLine, index);
+    MOZ_ASSERT(iaddress);
+    nsAutoString address;
+    rv = iaddress->GetData(address);
+    NS_ENSURE_SUCCESS(rv, rv);
+    addressLine.AppendElement(address);
+  }
+
+  IPCPaymentAddress ipcAddress(country, addressLine, region, regionCode, city,
+                               dependentLocality, postalCode, sortingCode,
+                               organization, recipient, phone);
+
   nsAutoString requestId(aRequestId);
   if (!SendChangeShippingAddress(requestId, ipcAddress)) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 nsresult
@@ -308,127 +355,10 @@ PaymentRequestParent::ActorDestroy(Actor
       return;
     }
     payments::PaymentRequest* rowRequest =
       static_cast<payments::PaymentRequest*>(request.get());
     MOZ_ASSERT(rowRequest);
     rowRequest->SetIPC(nullptr);
   }
 }
-
-nsresult
-PaymentRequestParent::SerializeAddress(IPCPaymentAddress& aIPCAddress,
-                                       nsIPaymentAddress* aAddress)
-{
-  // address can be nullptr
-  if (!aAddress) {
-    return NS_OK;
-  }
-  nsAutoString country;
-  nsresult rv = aAddress->GetCountry(country);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIArray> iaddressLine;
-  rv = aAddress->GetAddressLine(getter_AddRefs(iaddressLine));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString region;
-  rv = aAddress->GetRegion(region);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString regionCode;
-  rv = aAddress->GetRegionCode(regionCode);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString city;
-  rv = aAddress->GetCity(city);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString dependentLocality;
-  rv = aAddress->GetDependentLocality(dependentLocality);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString postalCode;
-  rv = aAddress->GetPostalCode(postalCode);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString sortingCode;
-  rv = aAddress->GetSortingCode(sortingCode);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString organization;
-  rv = aAddress->GetOrganization(organization);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString recipient;
-  rv = aAddress->GetRecipient(recipient);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString phone;
-  rv = aAddress->GetPhone(phone);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsTArray<nsString> addressLine;
-  uint32_t length;
-  rv = iaddressLine->GetLength(&length);
-  NS_ENSURE_SUCCESS(rv, rv);
-  for (uint32_t index = 0; index < length; ++index) {
-    nsCOMPtr<nsISupportsString> iaddress = do_QueryElementAt(iaddressLine, index);
-    MOZ_ASSERT(iaddress);
-    nsAutoString address;
-    rv = iaddress->GetData(address);
-    NS_ENSURE_SUCCESS(rv, rv);
-    addressLine.AppendElement(address);
-  }
-
-  aIPCAddress = IPCPaymentAddress(country, addressLine, region, regionCode, city,
-                                  dependentLocality, postalCode, sortingCode,
-                                  organization, recipient, phone);
-  return NS_OK;
-}
-
-nsresult
-PaymentRequestParent::SerializeResponseData(IPCPaymentResponseData& aIPCData,
-                                            nsIPaymentResponseData* aData)
-{
-  NS_ENSURE_ARG_POINTER(aData);
-  uint32_t dataType;
-  NS_ENSURE_SUCCESS(aData->GetType(&dataType), NS_ERROR_FAILURE);
-  switch(dataType) {
-    case nsIPaymentResponseData::GENERAL_RESPONSE: {
-      nsCOMPtr<nsIGeneralResponseData> response = do_QueryInterface(aData);
-      MOZ_ASSERT(response);
-      IPCGeneralResponse data;
-      NS_ENSURE_SUCCESS(response->GetData(data.data()), NS_ERROR_FAILURE);
-      aIPCData = data;
-      break;
-    }
-    case nsIPaymentResponseData::BASICCARD_RESPONSE: {
-      nsCOMPtr<nsIBasicCardResponseData> response = do_QueryInterface(aData);
-      MOZ_ASSERT(response);
-      IPCBasicCardResponse data;
-      NS_ENSURE_SUCCESS(response->GetCardholderName(data.cardholderName()),
-                        NS_ERROR_FAILURE);
-      NS_ENSURE_SUCCESS(response->GetCardNumber(data.cardNumber()),
-                        NS_ERROR_FAILURE);
-      NS_ENSURE_SUCCESS(response->GetExpiryMonth(data.expiryMonth()),
-                        NS_ERROR_FAILURE);
-      NS_ENSURE_SUCCESS(response->GetExpiryYear(data.expiryYear()),
-                        NS_ERROR_FAILURE);
-      NS_ENSURE_SUCCESS(response->GetCardSecurityCode(data.cardSecurityCode()),
-                        NS_ERROR_FAILURE);
-      nsCOMPtr<nsIPaymentAddress> address;
-      NS_ENSURE_SUCCESS(response->GetBillingAddress(getter_AddRefs(address)),
-                        NS_ERROR_FAILURE);
-      IPCPaymentAddress ipcAddress;
-      NS_ENSURE_SUCCESS(SerializeAddress(ipcAddress, address), NS_ERROR_FAILURE);
-      data.billingAddress() = ipcAddress;
-      aIPCData = data;
-      break;
-    }
-    default: {
-      return NS_ERROR_FAILURE;
-    }
-  }
-  return NS_OK;
-}
 } // end of namespace dom
 } // end of namespace mozilla
--- a/dom/payments/ipc/PaymentRequestParent.h
+++ b/dom/payments/ipc/PaymentRequestParent.h
@@ -36,21 +36,16 @@ protected:
   RecvRequestPayment(const IPCPaymentActionRequest& aRequest) override;
 
   mozilla::ipc::IPCResult Recv__delete__() override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 private:
   ~PaymentRequestParent() = default;
 
-  nsresult SerializeAddress(IPCPaymentAddress& ipcAddress,
-                            nsIPaymentAddress* aAddress);
-  nsresult SerializeResponseData(IPCPaymentResponseData& ipcData,
-                                 nsIPaymentResponseData* aData);
-
   bool mActorAlive;
   uint64_t mTabId;
   nsString mRequestId;
 };
 
 } // end of namespace dom
 } // end of namespace mozilla
 
--- a/dom/payments/test/BasiccardChromeScript.js
+++ b/dom/payments/test/BasiccardChromeScript.js
@@ -24,34 +24,16 @@ billingAddress.init("USA",              
                      "San Bruno",        // city
                      "",                 // dependent locality
                      "94066",            // postal code
                      "123456",           // sorting code
                      "",                 // organization
                      "Bill A. Pacheco",  // recipient
                      "+14344413879"); // phone
 
-const specialAddress = Cc["@mozilla.org/dom/payments/payment-address;1"].
-                           createInstance(Ci.nsIPaymentAddress);
-const specialAddressLine = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
-const specialData = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
-specialData.data = ":$%@&*";
-specialAddressLine.appendElement(specialData);
-specialAddress.init("USA",               // country
-                     specialAddressLine, // address line
-                     "CA",               // region
-                     "CA",               // region code
-                     "San Bruno",        // city
-                     "",                 // dependent locality
-                     "94066",            // postal code
-                     "123456",           // sorting code
-                     "",                 // organization
-                     "Bill A. Pacheco",  // recipient
-                     "+14344413879"); // phone
-
 const basiccardResponseData = Cc["@mozilla.org/dom/payments/basiccard-response-data;1"].
                                  createInstance(Ci.nsIBasicCardResponseData);
 
 const showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"].
                         createInstance(Ci.nsIPaymentShowActionResponse);
 
 function abortPaymentResponse(requestId) {
   let abortResponse = Cc["@mozilla.org/dom/payments/payment-abort-action-response;1"].
@@ -122,58 +104,24 @@ const simpleResponseUI = {
   completePayment: completePaymentResponse,
   updatePayment: function(requestId) {
   },
   closePayment: function(requestId) {
   },
   QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
 };
 
-const specialAddressUI = {
-  showPayment: function(requestId) {
-    try {
-      basiccardResponseData.initData("Bill A. Pacheco",  // cardholderName
-                                     "4916855166538720", // cardNumber
-                                     "01",               // expiryMonth
-                                     "2024",             // expiryYear
-                                     "180",              // cardSecurityCode
-                                     specialAddress);    // billingAddress
-    } catch (e) {
-      emitTestFail("Fail to initialize basic card response data.");
-    }
-    showResponse.init(requestId,
-                      Ci.nsIPaymentActionResponse.PAYMENT_ACCEPTED,
-                      "basic-card",         // payment method
-                      basiccardResponseData,// payment method data
-                      "Bill A. Pacheco",    // payer name
-                      "",                   // payer email
-                      "");                  // payer phone
-    paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
-  },
-  abortPayment: abortPaymentResponse,
-  completePayment: completePaymentResponse,
-  updatePayment: function(requestId) {
-  },
-  closePayment: function (requestId) {
-  },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
-};
-
 addMessageListener("set-detailed-ui-service", function() {
   paymentSrv.setTestingUIService(detailedResponseUI.QueryInterface(Ci.nsIPaymentUIService));
 });
 
 addMessageListener("set-simple-ui-service", function() {
   paymentSrv.setTestingUIService(simpleResponseUI.QueryInterface(Ci.nsIPaymentUIService));
 });
 
-addMessageListener("set-special-address-ui-service", function() {
-  paymentSrv.setTestingUIService(specialAddressUI.QueryInterface(Ci.nsIPaymentUIService));
-});
-
 addMessageListener("error-response-test", function() {
   // test empty cardNumber
   try {
     basiccardResponseData.initData("", "", "", "", "", null);
     emitTestFail("BasicCardResponse should not be initialized with empty cardNumber.");
   } catch (e) {
     if (e.name != "NS_ERROR_FAILURE") {
       emitTestFail("Empty cardNumber expected 'NS_ERROR_FAILURE', but got " + e.name + ".");
--- a/dom/payments/test/test_basiccard.html
+++ b/dom/payments/test/test_basiccard.html
@@ -236,34 +236,16 @@ https://bugzilla.mozilla.org/show_bug.cg
         });
       }).catch( e => {
         ok(false, "Unexpected error: " + e.name);
         resolve();
       }).finally(handler.destruct);
     });
   }
 
-  function testSpecialAddressResponse() {
-    const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
-    gScript.sendAsyncMessage("set-special-address-ui-service");
-    return new Promise((resolve, reject) => {
-      const payRequest = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
-      payRequest.show().then(response => {
-        ok(response.details, "BasiccardResponse should exist.");
-        ok(response.details.billingAddress,
-           "BasiccardResponse.billingAddress should exist.");
-        is(response.details.billingAddress.addressLine[0], ":$%@&*",
-           "AddressLine should be ':$%@&*'");
-        response.complete("success").then(()=>{
-          resolve();
-        });
-      }).finally(handler.destruct);
-    });
-  }
-
   function testBasicCardErrorResponse() {
     return new Promise((resolve, reject) => {
       gScript.addMessageListener("error-response-complete",
                                  function errorResponseCompleteHandler() {
         gScript.removeMessageListener("error-response-complete",
                                       errorResponseCompleteHandler);
         resolve();
       });
@@ -285,17 +267,16 @@ https://bugzilla.mozilla.org/show_bug.cg
     testBasicCardRequestWithErrorTypes()
     .then(testBasicCardRequestWithErrorNetworks)
     .then(testBasicCardRequestWithUnconvertableData)
     .then(testBasicCardRequestWithNullData)
     .then(testBasicCardRequestWithEmptyData)
     .then(testCanMakePaymentWithBasicCardRequest)
     .then(testBasicCardSimpleResponse)
     .then(testBasicCardDetailedResponse)
-    .then(testSpecialAddressResponse)
     .then(testBasicCardErrorResponse)
     .then(teardown)
     .catch( e => {
       ok(false, "Unexpected error: " + e.name);
       SimpleTest.finish();
     });
   }