org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard Java Examples

The following examples show how to use org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AutofillPaymentInstrument.java    From AndroidChromium with Apache License 2.0 6 votes vote down vote up
/**
 * Updates the instrument and marks it "complete." Called after the user has edited this
 * instrument.
 *
 * @param card           The new credit card to use. The GUID should not change.
 * @param billingAddress The billing address for the card. The GUID should match the billing
 *                       address ID of the new card to use.
 */
public void completeInstrument(CreditCard card, AutofillProfile billingAddress) {
    assert card != null;
    assert billingAddress != null;
    assert card.getBillingAddressId() != null;
    assert card.getBillingAddressId().equals(billingAddress.getGUID());
    assert card.getIssuerIconDrawableId() != 0;
    assert AutofillAddress.checkAddressCompletionStatus(billingAddress)
            == AutofillAddress.COMPLETE;

    mCard = card;
    mBillingAddress = billingAddress;
    updateIdentifierLabelsAndIcon(card.getGUID(), card.getObfuscatedNumber(), card.getName(),
            null, ApiCompatibilityUtils.getDrawable(
                          mContext.getResources(), card.getIssuerIconDrawableId()));
    checkAndUpateCardCompleteness();
    assert mIsComplete;
    assert mHasValidNumberAndName;
}
 
Example #2
Source File: AutofillPaymentInstrument.java    From 365browser with Apache License 2.0 6 votes vote down vote up
/**
 * Updates the instrument and marks it "complete." Called after the user has edited this
 * instrument.
 *
 * @param card           The new credit card to use. The GUID should not change.
 * @param methodName     The payment method name to use for this instrument, e.g., "visa",
 *                       "basic-card".
 * @param billingAddress The billing address for the card. The GUID should match the billing
 *                       address ID of the new card to use.
 */
public void completeInstrument(
        CreditCard card, String methodName, AutofillProfile billingAddress) {
    assert card != null;
    assert methodName != null;
    assert billingAddress != null;
    assert card.getBillingAddressId() != null;
    assert card.getBillingAddressId().equals(billingAddress.getGUID());
    assert card.getIssuerIconDrawableId() != 0;
    assert AutofillAddress.checkAddressCompletionStatus(
            billingAddress, AutofillAddress.IGNORE_PHONE_COMPLETENESS_CHECK)
            == AutofillAddress.COMPLETE;

    mCard = card;
    mMethodName = methodName;
    mBillingAddress = billingAddress;

    Context context = ChromeActivity.fromWebContents(mWebContents);
    if (context == null) return;

    updateIdentifierLabelsAndIcon(card.getGUID(), card.getObfuscatedNumber(), card.getName(),
            null, AppCompatResources.getDrawable(context, card.getIssuerIconDrawableId()));
    checkAndUpateCardCompleteness(context);
    assert mIsComplete;
    assert mHasValidNumberAndName;
}
 
Example #3
Source File: AutofillPaymentInstrument.java    From 365browser with Apache License 2.0 6 votes vote down vote up
@Override
public void onFullCardDetails(CreditCard updatedCard, String cvc) {
    // Keep the cvc for after the normalization.
    mSecurityCode = cvc;

    // The card number changes for unmasked cards.
    assert updatedCard.getNumber().length() > 4;
    mCard.setNumber(updatedCard.getNumber());

    // Update the card's expiration date.
    mCard.setMonth(updatedCard.getMonth());
    mCard.setYear(updatedCard.getYear());

    mIsWaitingForFullCardDetails = false;

    // Show the loading UI while the address gets normalized.
    mCallback.onInstrumentDetailsLoadingWithoutUI();

    // Wait for the billing address normalization before sending the instrument details.
    if (!mIsWaitingForBillingNormalization) sendInstrumentDetails();
}
 
Example #4
Source File: AutofillPaymentInstrument.java    From 365browser with Apache License 2.0 6 votes vote down vote up
/**
 * Builds a payment instrument for the given credit card.
 *
 * @param webContents    The web contents where PaymentRequest was invoked.
 * @param card           The autofill card that can be used for payment.
 * @param billingAddress The billing address for the card.
 * @param methodName     The payment method name, e.g., "basic-card", "visa", amex", or null.
 */
public AutofillPaymentInstrument(WebContents webContents, CreditCard card,
        @Nullable AutofillProfile billingAddress, @Nullable String methodName) {
    super(card.getGUID(), card.getObfuscatedNumber(), card.getName(), null);
    mWebContents = webContents;
    mCard = card;
    mBillingAddress = billingAddress;
    mIsEditable = true;
    mMethodName = methodName;

    Context context = ChromeActivity.fromWebContents(mWebContents);
    if (context == null) return;

    if (card.getIssuerIconDrawableId() != 0) {
        updateDrawableIcon(
                AppCompatResources.getDrawable(context, card.getIssuerIconDrawableId()));
    }

    checkAndUpateCardCompleteness(context);
}
 
Example #5
Source File: AutofillLocalCardEditor.java    From AndroidChromium with Apache License 2.0 6 votes vote down vote up
@Override
protected boolean saveEntry() {
    // Remove all spaces in editText.
    String cardNumber = mNumberText.getText().toString().replaceAll("\\s+", "");
    PersonalDataManager personalDataManager = PersonalDataManager.getInstance();
    // Card Payment Type will be empty if credit card number is not valid.
    if (TextUtils.isEmpty(personalDataManager.getBasicCardPaymentType(cardNumber,
            true /* emptyIfInvalid */))) {
        mNumberLabel.setError(mContext.getString(
                R.string.payments_card_number_invalid_validation_message));
        return false;
    }
    CreditCard card = new CreditCard(mGUID, AutofillPreferences.SETTINGS_ORIGIN,
            true /* isLocal */, false /* isCached */, mNameText.getText().toString().trim(),
            cardNumber, "" /* obfuscatedNumber */,
            String.valueOf(mExpirationMonth.getSelectedItemPosition() + 1),
            (String) mExpirationYear.getSelectedItem(), "" /* basicCardPaymentType */,
            0 /* issuerIconDrawableId */,
            ((AutofillProfile) mBillingAddress.getSelectedItem()).getGUID() /* billing */,
            "" /* serverId */);
    personalDataManager.setCreditCard(card);
    return true;
}
 
Example #6
Source File: AutofillPreferences.java    From AndroidChromium with Apache License 2.0 6 votes vote down vote up
private void rebuildCreditCardList() {
    PreferenceGroup profileCategory =
            (PreferenceGroup) findPreference(PREF_AUTOFILL_CREDIT_CARDS);
    profileCategory.removeAll();
    for (CreditCard card : PersonalDataManager.getInstance().getCreditCardsForSettings()) {
        // Add an item on the current page...
        Preference pref = new Preference(getActivity());
        pref.setTitle(card.getObfuscatedNumber());
        pref.setSummary(card.getFormattedExpirationDate(getActivity()));

        if (card.getIsLocal()) {
            pref.setFragment(AutofillLocalCardEditor.class.getName());
        } else {
            pref.setFragment(AutofillServerCardEditor.class.getName());
            pref.setWidgetLayoutResource(R.layout.autofill_server_data_label);
        }

        Bundle args = pref.getExtras();
        args.putString(AUTOFILL_GUID, card.getGUID());
        profileCategory.addPreference(pref);
    }
}
 
Example #7
Source File: AutofillPreferences.java    From delion with Apache License 2.0 6 votes vote down vote up
private void rebuildCreditCardList() {
    PreferenceGroup profileCategory =
            (PreferenceGroup) findPreference(PREF_AUTOFILL_CREDIT_CARDS);
    profileCategory.removeAll();
    for (CreditCard card : PersonalDataManager.getInstance().getCreditCardsForSettings()) {
        // Add an item on the current page...
        Preference pref = new Preference(getActivity());
        pref.setTitle(card.getObfuscatedNumber());
        pref.setSummary(card.getFormattedExpirationDate(getActivity()));

        if (card.getIsLocal()) {
            pref.setFragment(AutofillLocalCardEditor.class.getName());
        } else {
            pref.setFragment(AutofillServerCardEditor.class.getName());
            pref.setWidgetLayoutResource(R.layout.autofill_server_data_label);
        }

        Bundle args = pref.getExtras();
        args.putString(AUTOFILL_GUID, card.getGUID());
        profileCategory.addPreference(pref);
    }
}
 
Example #8
Source File: AutofillPaymentApp.java    From delion with Apache License 2.0 6 votes vote down vote up
@Override
public void getInstruments(JSONObject unusedDetails, final InstrumentsCallback callback) {
    PersonalDataManager pdm = PersonalDataManager.getInstance();
    List<CreditCard> cards = pdm.getCreditCardsToSuggest();
    final List<PaymentInstrument> instruments = new ArrayList<>(cards.size());

    for (int i = 0; i < cards.size(); i++) {
        CreditCard card = cards.get(i);
        AutofillProfile billingAddress = TextUtils.isEmpty(card.getBillingAddressId())
                ? null : pdm.getProfile(card.getBillingAddressId());
        instruments.add(new AutofillPaymentInstrument(mWebContents, card, billingAddress));
    }

    new Handler().post(new Runnable() {
        @Override
        public void run() {
            callback.onInstrumentsReady(AutofillPaymentApp.this, instruments);
        }
    });
}
 
Example #9
Source File: AutofillLocalCardEditor.java    From 365browser with Apache License 2.0 6 votes vote down vote up
@Override
protected boolean saveEntry() {
    // Remove all spaces in editText.
    String cardNumber = mNumberText.getText().toString().replaceAll("\\s+", "");
    PersonalDataManager personalDataManager = PersonalDataManager.getInstance();
    // Issuer network will be empty if credit card number is not valid.
    if (TextUtils.isEmpty(personalDataManager.getBasicCardIssuerNetwork(
                cardNumber, true /* emptyIfInvalid */))) {
        mNumberLabel.setError(mContext.getString(
                R.string.payments_card_number_invalid_validation_message));
        return false;
    }
    CreditCard card = new CreditCard(mGUID, AutofillAndPaymentsPreferences.SETTINGS_ORIGIN,
            true /* isLocal */, false /* isCached */, mNameText.getText().toString().trim(),
            cardNumber, "" /* obfuscatedNumber */,
            String.valueOf(mExpirationMonth.getSelectedItemPosition() + 1),
            (String) mExpirationYear.getSelectedItem(), "" /* basicCardPaymentType */,
            0 /* issuerIconDrawableId */,
            ((AutofillProfile) mBillingAddress.getSelectedItem()).getGUID() /* billing */,
            "" /* serverId */);
    personalDataManager.setCreditCard(card);
    return true;
}
 
Example #10
Source File: CardEditor.java    From AndroidChromium with Apache License 2.0 5 votes vote down vote up
/**
 * Saves the edited credit card.
 *
 * If this is a server card, then only its billing address identifier is updated.
 *
 * If this is a new local card, then it's saved on this device only if the user has checked the
 * "save this card" checkbox.
 */
private void commitChanges(CreditCard card, boolean isNewCard) {
    card.setBillingAddressId(mBillingAddressField.getValue().toString());

    PersonalDataManager pdm = PersonalDataManager.getInstance();
    if (!card.getIsLocal()) {
        pdm.updateServerCardBillingAddress(card.getServerId(), card.getBillingAddressId());
        return;
    }

    card.setNumber(mNumberField.getValue().toString().replace(" ", "").replace("-", ""));
    card.setName(mNameField.getValue().toString());
    card.setMonth(mMonthField.getValue().toString());
    card.setYear(mYearField.getValue().toString());

    // Calculate the basic card payment type, obfuscated number, and the icon for this card.
    // All of these depend on the card number. The type is sent to the merchant website. The
    // obfuscated number and the icon are displayed in the user interface.
    CreditCard displayableCard = pdm.getCreditCardForNumber(card.getNumber());
    card.setBasicCardPaymentType(displayableCard.getBasicCardPaymentType());
    card.setObfuscatedNumber(displayableCard.getObfuscatedNumber());
    card.setIssuerIconDrawableId(displayableCard.getIssuerIconDrawableId());

    if (!isNewCard) {
        pdm.setCreditCard(card);
        return;
    }

    if (mSaveCardCheckbox != null && mSaveCardCheckbox.isChecked()) {
        card.setGUID(pdm.setCreditCard(card));
    }
}
 
Example #11
Source File: AutofillPaymentInstrument.java    From AndroidChromium with Apache License 2.0 5 votes vote down vote up
/**
 * Builds a payment instrument for the given credit card.
 *
 * @param context        The application context.
 * @param webContents    The web contents where PaymentRequest was invoked.
 * @param card           The autofill card that can be used for payment.
 * @param billingAddress The billing address for the card.
 */
public AutofillPaymentInstrument(Context context, WebContents webContents, CreditCard card,
        @Nullable AutofillProfile billingAddress) {
    super(card.getGUID(), card.getObfuscatedNumber(), card.getName(),
            card.getIssuerIconDrawableId() == 0
            ? null
            : ApiCompatibilityUtils.getDrawable(
                    context.getResources(), card.getIssuerIconDrawableId()));
    mContext = context;
    mWebContents = webContents;
    mCard = card;
    mBillingAddress = billingAddress;
    mIsEditable = true;
    checkAndUpateCardCompleteness();
}
 
Example #12
Source File: AutofillPaymentInstrument.java    From AndroidChromium with Apache License 2.0 5 votes vote down vote up
@Override
public void onFullCardDetails(CreditCard updatedCard, String cvc) {
    // Keep the cvc for after the normalization.
    mSecurityCode = cvc;

    // The card number changes for unmasked cards.
    assert updatedCard.getNumber().length() > 4;
    mCard.setNumber(updatedCard.getNumber());

    // Update the card's expiration date.
    mCard.setMonth(updatedCard.getMonth());
    mCard.setYear(updatedCard.getYear());

    mIsWaitingForFullCardDetails = false;

    // Show the loading UI while the address gets normalized.
    mCallback.loadingInstrumentDetails();

    // Wait for the billing address normalization before sending the instrument details.
    if (mIsWaitingForBillingNormalization) {
        // If the normalization is not completed yet, Start a timer to cancel it if it takes too
        // long.
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                onAddressNormalized(null);
            }
        }, PersonalDataManager.getInstance().getNormalizationTimeoutMS());

        return;
    } else {
        sendIntrumentDetails();
    }
}
 
Example #13
Source File: AutofillPaymentInstrument.java    From delion with Apache License 2.0 5 votes vote down vote up
/**
 * Builds a payment instrument for the given credit card.
 *
 * @param webContents    The web contents where PaymentRequest was invoked.
 * @param card           The autofill card that can be used for payment.
 * @param billingAddress The optional billing address for the card.
 */
public AutofillPaymentInstrument(
        WebContents webContents, CreditCard card, @Nullable AutofillProfile billingAddress) {
    super(card.getGUID(), card.getObfuscatedNumber(), card.getName(),
            card.getIssuerIconDrawableId());
    mWebContents = webContents;
    mCard = card;
    mBillingAddress = billingAddress;
}
 
Example #14
Source File: AutofillPaymentApp.java    From AndroidChromium with Apache License 2.0 5 votes vote down vote up
@Override
public void getInstruments(
        Map<String, PaymentMethodData> unusedMethodData, final InstrumentsCallback callback) {
    PersonalDataManager pdm = PersonalDataManager.getInstance();
    List<CreditCard> cards = pdm.getCreditCardsToSuggest();
    final List<PaymentInstrument> instruments = new ArrayList<>(cards.size());

    for (int i = 0; i < cards.size(); i++) {
        CreditCard card = cards.get(i);
        AutofillProfile billingAddress = TextUtils.isEmpty(card.getBillingAddressId())
                ? null : pdm.getProfile(card.getBillingAddressId());

        if (billingAddress != null
                && AutofillAddress.checkAddressCompletionStatus(billingAddress)
                        != AutofillAddress.COMPLETE) {
            billingAddress = null;
        }

        instruments.add(new AutofillPaymentInstrument(mContext, mWebContents, card,
                billingAddress));
    }

    new Handler().post(new Runnable() {
        @Override
        public void run() {
            callback.onInstrumentsReady(AutofillPaymentApp.this, instruments);
        }
    });
}
 
Example #15
Source File: AutofillLocalCardEditor.java    From delion with Apache License 2.0 5 votes vote down vote up
@Override
protected void saveEntry() {
    // Remove all spaces in editText.
    String cardNumber = mNumberText.getText().toString().replaceAll("\\s+", "");
    CreditCard card = new CreditCard(mGUID, AutofillPreferences.SETTINGS_ORIGIN,
            true /* isLocal */, false /* isCached */, mNameText.getText().toString().trim(),
            cardNumber, "" /* obfuscatedNumber */,
            String.valueOf(mExpirationMonth.getSelectedItemPosition() + 1),
            (String) mExpirationYear.getSelectedItem(), "" /* basicCardPaymentType */,
            0 /* issuerIconDrawableId */,
            ((AutofillProfile) mBillingAddress.getSelectedItem()).getGUID() /* billing */);
    PersonalDataManager.getInstance().setCreditCard(card);
}
 
Example #16
Source File: CardEditor.java    From 365browser with Apache License 2.0 5 votes vote down vote up
/**
 * Saves the edited credit card.
 *
 * If this is a server card, then only its billing address identifier is updated.
 *
 * If this is a new local card, then it's saved on this device only if the user has checked the
 * "save this card" checkbox.
 */
private void commitChanges(CreditCard card, boolean isNewCard) {
    card.setBillingAddressId(mBillingAddressField.getValue().toString());

    PersonalDataManager pdm = PersonalDataManager.getInstance();
    if (!card.getIsLocal()) {
        pdm.updateServerCardBillingAddress(card);
        return;
    }

    card.setNumber(removeSpaceAndBar(mNumberField.getValue()));
    card.setName(mNameField.getValue().toString());
    card.setMonth(mMonthField.getValue().toString());
    card.setYear(mYearField.getValue().toString());

    // Calculate the basic card issuer network, obfuscated number, and the icon for this card.
    // All of these depend on the card number. The issuer network is sent to the merchant
    // website. The obfuscated number and the icon are displayed in the user interface.
    CreditCard displayableCard = pdm.getCreditCardForNumber(card.getNumber());
    card.setBasicCardIssuerNetwork(displayableCard.getBasicCardIssuerNetwork());
    card.setObfuscatedNumber(displayableCard.getObfuscatedNumber());
    card.setIssuerIconDrawableId(displayableCard.getIssuerIconDrawableId());

    if (!isNewCard) {
        pdm.setCreditCard(card);
        return;
    }

    if (mSaveCardCheckbox != null && mSaveCardCheckbox.isChecked()) {
        card.setGUID(pdm.setCreditCard(card));
    }
}
 
Example #17
Source File: AutofillPaymentInstrument.java    From AndroidChromium with Apache License 2.0 4 votes vote down vote up
/** @return The credit card represented by this payment instrument. */
public CreditCard getCard() {
    return mCard;
}
 
Example #18
Source File: AutofillPaymentApp.java    From 365browser with Apache License 2.0 4 votes vote down vote up
@Override
public void getInstruments(Map<String, PaymentMethodData> methodDataMap, String unusedOrigin,
        String unusedIFRameOrigin, byte[][] unusedCertificateChain, PaymentItem unusedTotal,
        final InstrumentsCallback callback) {
    PersonalDataManager pdm = PersonalDataManager.getInstance();
    List<CreditCard> cards = pdm.getCreditCardsToSuggest();
    final List<PaymentInstrument> instruments = new ArrayList<>(cards.size());

    Set<String> basicCardSupportedNetworks =
            convertBasicCardToNetworks(methodDataMap.get(BASIC_CARD_METHOD_NAME));

    for (int i = 0; i < cards.size(); i++) {
        CreditCard card = cards.get(i);
        AutofillProfile billingAddress = TextUtils.isEmpty(card.getBillingAddressId())
                ? null : pdm.getProfile(card.getBillingAddressId());

        if (billingAddress != null
                && AutofillAddress.checkAddressCompletionStatus(
                           billingAddress, AutofillAddress.IGNORE_PHONE_COMPLETENESS_CHECK)
                        != AutofillAddress.COMPLETE) {
            billingAddress = null;
        }

        if (billingAddress == null) card.setBillingAddressId(null);

        String methodName = null;
        if (basicCardSupportedNetworks != null
                && basicCardSupportedNetworks.contains(card.getBasicCardIssuerNetwork())) {
            methodName = BASIC_CARD_METHOD_NAME;
        } else if (methodDataMap.containsKey(card.getBasicCardIssuerNetwork())) {
            methodName = card.getBasicCardIssuerNetwork();
        }

        if (methodName != null) {
            instruments.add(new AutofillPaymentInstrument(
                    mWebContents, card, billingAddress, methodName));
        }
    }

    new Handler().post(new Runnable() {
        @Override
        public void run() {
            callback.onInstrumentsReady(AutofillPaymentApp.this, instruments);
        }
    });
}
 
Example #19
Source File: AutofillPaymentInstrument.java    From 365browser with Apache License 2.0 4 votes vote down vote up
/** @return The credit card represented by this payment instrument. */
public CreditCard getCard() {
    return mCard;
}
 
Example #20
Source File: CardEditor.java    From AndroidChromium with Apache License 2.0 4 votes vote down vote up
/**
 * Adds the billing address dropdown to the editor with the following items.
 *
 * | "select"           |
 * | complete address 1 |
 * | complete address 2 |
 *      ...
 * | complete address n |
 * | "add address"      |
 */
private void addBillingAddressDropdown(EditorModel editor, final CreditCard card) {
    final List<DropdownKeyValue> billingAddresses = new ArrayList<>();

    for (int i = 0; i < mProfilesForBillingAddress.size(); ++i) {
        billingAddresses.add(new DropdownKeyValue(mProfilesForBillingAddress.get(i).getGUID(),
                mProfilesForBillingAddress.get(i).getLabel()));
    }

    billingAddresses.add(new DropdownKeyValue(BILLING_ADDRESS_ADD_NEW,
            mContext.getString(R.string.autofill_create_profile)));

    // Don't cache the billing address dropdown, because the user may have added or removed
    // profiles. Also pass the "Select" dropdown item as a hint to the dropdown constructor.
    mBillingAddressField = EditorFieldModel.createDropdown(
            mContext.getString(R.string.autofill_credit_card_editor_billing_address),
            billingAddresses, mContext.getString(R.string.select));

    // The billing address is required.
    mBillingAddressField.setRequiredErrorMessage(
            mContext.getString(R.string.payments_field_required_validation_message));

    mBillingAddressField.setDropdownCallback(new Callback<Pair<String, Runnable>>() {
        @Override
        public void onResult(final Pair<String, Runnable> eventData) {
            if (!BILLING_ADDRESS_ADD_NEW.equals(eventData.first)) {
                if (mObserverForTest != null) {
                    mObserverForTest.onPaymentRequestServiceBillingAddressChangeProcessed();
                }
                return;
            }

            mAddressEditor.edit(null, new Callback<AutofillAddress>() {
                @Override
                public void onResult(AutofillAddress billingAddress) {
                    if (billingAddress == null) {
                        // User has cancelled the address editor.
                        mBillingAddressField.setValue(null);
                    } else {
                        // User has added a new complete address. Add it to the top of the
                        // dropdown.
                        mProfilesForBillingAddress.add(billingAddress.getProfile());
                        billingAddresses.add(
                                0, new DropdownKeyValue(billingAddress.getIdentifier(),
                                           billingAddress.getSublabel()));
                        mBillingAddressField.setDropdownKeyValues(billingAddresses);
                        mBillingAddressField.setValue(billingAddress.getIdentifier());
                    }

                    // Let the card editor UI re-read the model and re-create UI elements.
                    mHandler.post(eventData.second);
                }
            });
        }
    });

    if (mBillingAddressField.getDropdownKeys().contains(card.getBillingAddressId())) {
        mBillingAddressField.setValue(card.getBillingAddressId());
    }

    editor.addField(mBillingAddressField);
}
 
Example #21
Source File: AutofillPaymentInstrument.java    From delion with Apache License 2.0 4 votes vote down vote up
@Override
public void onFullCardDetails(CreditCard card, String cvc) {
    StringWriter stringWriter = new StringWriter();
    JsonWriter json = new JsonWriter(stringWriter);
    try {
        json.beginObject();

        json.name("cardholderName").value(card.getName());
        json.name("cardNumber").value(card.getNumber());
        json.name("expiryMonth").value(card.getMonth());
        json.name("expiryYear").value(card.getYear());
        json.name("cardSecurityCode").value(cvc);

        if (mBillingAddress != null) {
            json.name("billingAddress").beginObject();

            json.name("country").value(ensureNotNull(mBillingAddress.getCountryCode()));
            json.name("region").value(ensureNotNull(mBillingAddress.getRegion()));
            json.name("city").value(ensureNotNull(mBillingAddress.getLocality()));
            json.name("dependentLocality")
                    .value(ensureNotNull(mBillingAddress.getDependentLocality()));

            json.name("addressLine").beginArray();
            String multipleLines = ensureNotNull(mBillingAddress.getStreetAddress());
            if (!TextUtils.isEmpty(multipleLines)) {
                String[] lines = multipleLines.split("\n");
                for (int i = 0; i < lines.length; i++) {
                    json.value(lines[i]);
                }
            }
            json.endArray();

            json.name("postalCode").value(ensureNotNull(mBillingAddress.getPostalCode()));
            json.name("sortingCode").value(ensureNotNull(mBillingAddress.getSortingCode()));
            json.name("languageCode").value(ensureNotNull(mBillingAddress.getLanguageCode()));
            json.name("organization").value(ensureNotNull(mBillingAddress.getCompanyName()));
            json.name("recipient").value(ensureNotNull(mBillingAddress.getFullName()));
            json.name("careOf").value("");
            json.name("phone").value(ensureNotNull(mBillingAddress.getPhoneNumber()));

            json.endObject();
        }

        json.endObject();
    } catch (IOException e) {
        mCallback.onInstrumentDetailsError();
        return;
    }

    mCallback.onInstrumentDetailsReady(card.getBasicCardPaymentType(), stringWriter.toString());
}