TL;DR: Can I process a transaction using a PaymentDataRequest built using WalletConstants.TOTAL_PRICE_STATUS_ESTIMATED as the TransactionInfo's "TotalPriceStatus"?
Full Issue Description
I have an app that currently has AndroidPay integrated as a payment method, and I want to migrate this to use the new Google Payment API.
Users can purchase things that are shipped to them, and since shipping costs can change based on location, I can't calculate the final cost of the order until I get the user's shipping address from the MaskedWallet (AndroidPay) or PaymentData (Google Payment). When using AndroidPay, the user is shown a bottom-sheet dialog when I request the MaskedWallet, then I can calculate the order total, and then request the FullWallet with an exact amount to charge the user.
If I follow the same basic pattern with Google Payment, I request a PaymentData like so:
PaymentDataRequest.Builder request = PaymentDataRequest.newBuilder()
.setTransactionInfo(TransactionInfo.newBuilder()
.setTotalPriceStatus(WalletConstants.TOTAL_PRICE_STATUS_ESTIMATED)
.setTotalPrice("123")
.setCurrencyCode("USD")
.build())
.addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_CARD)
.addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD)
.setPhoneNumberRequired(true)
.setEmailRequired(true)
.setShippingAddressRequired(true)
.setPaymentMethodTokenizationParameters(getTokenizationParameters())
.setCardRequirements(getCardRequirements());
where getTokenizationParameters() and getCardRequirements() are locally defined helper methods. After I make this request, a dialog is shown to the user that confirms their address and credit card (just like requesting the MaskedWallet for AndroidPay), then I show a confirmation UI of my own that shows a breakdown in the price. When the user clicks to confirm the purchase and place the order, I'm creating another PaymentDataRequest, but this time using WalletConstants.TOTAL_PRICE_STATUS_FINAL in the TransactionInfo because I know know exactly how much the customer will be charged, like so:
PaymentDataRequest.Builder request = PaymentDataRequest.newBuilder()
.setTransactionInfo(TransactionInfo.newBuilder()
.setTotalPriceStatus(WalletConstants.TOTAL_PRICE_STATUS_FINAL)
.setTotalPrice("133.5")
.setCurrencyCode("USD")
.build())
.addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_CARD)
.addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD)
.setPhoneNumberRequired(true)
.setEmailRequired(true)
.setUiRequired(false)
.setShippingAddressRequired(true)
.setPaymentMethodTokenizationParameters(getTokenizationParameters())
.setCardRequirements(getCardRequirements());
I'm doing this second request in part because this mirrors the process used in Android Pay with a FullWallet, but the UX is terrible because of this second dialog.
Do I have to create a PaymentDataRequest using WalletConstants.TOTAL_PRICE_STATUS_FINAL to get a PaymentData that I can use to charge the user, or can I use WalletConstants.TOTAL_PRICE_STATUS_ESTIMATED and use that PaymentData to charge the user, even though the exact dollar amount the user is charged may be different from the amount I created the request with?