Reputation: 236
TL;DR: Can I process a transaction using a PaymentDataRequest
built using WalletConstants.TOTAL_PRICE_STATUS_ESTIMATED
as the TransactionInfo
's "TotalPriceStatus"?
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?
Upvotes: 0
Views: 515
Reputation: 5534
As you correctly pointed out, unlike the old Android Pay API which had loadMaskedWallet
and loadFullWallet
that were supposed to be called in different parts of the flow, the Google Pay API only has a single loadPaymentData
call which can be, in this sense, considered a combination of the two (i.e. calling loadFullWallet
immediately after loadMaskedWallet
).
This means that there's no need to make the second PaymentDataRequest
- since your final price is not known when you request the payment credentials from Google, TOTAL_PRICE_STATUS_ESTIMATED
is the correct approach. Once you've received the payment credentials successfully, there's no need to make any further calls to the API.
Keep in mind that Google does not process transactions, so you would still need to provide your payment processor / gateway with the correct final amount.
Upvotes: 1