Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should API support billing address capture (for tax computation)? #27

Closed
ianbjacobs opened this issue Mar 9, 2016 · 59 comments
Closed

Should API support billing address capture (for tax computation)? #27

ianbjacobs opened this issue Mar 9, 2016 · 59 comments

Comments

@ianbjacobs
Copy link
Collaborator

@ianbjacobs ianbjacobs commented Mar 9, 2016

During the Feb FTF meeting [1], Vincent Kuntz pointed out that in Europe, billing address is required to compute VAT. The use case is that you purchase something in one country (where VAT is applied) but it is being shipped to another.

Thus, for some tax computations, do we need billing address (or some portion of it, like "country")?

[1] https://www.w3.org/2016/02/24-wpwg-minutes

@mattsaxon mattsaxon added this to the Priority: High milestone Mar 21, 2016
@djackso3
Copy link

@djackso3 djackso3 commented Apr 8, 2016

The method by which many payment systems work (especially in card) is to verify against billing address so billing address is required for some payment types and providers. In addition, some items will require the KYC address (government functions like BMV transactions). Delivery address is not always interesting to the payments process itself, but could be used if there is an AML issue with respect to shipping location of product that requires filtering by the payments provider. Lastly, a growing number of consumers provide KYC address -- because it is legally mandated -- and billing address for convenience -- yet have a fluctuating shipping address which generally in not germane to the payments process -- however, could be for filtering requirements as mentioned above. There are excellent examples of payment systems which cease working because of confusion of KYC / billing address having a mismatch against shipping address at the merchant. Personally over the last 6 months I have been working with Bank of America on this exact issue. The bank made an IT change which confused KYC and billing address. Once that happened, Delta Airlines refused to accept payment for a ticket because of the mismatch issue. My "delivery" address at the merchant (Delta) was equal to the billing address. So when I changed to the KYC address for approval of the payment, Delta refused again because they had a merchant mismatch of their delivery address of record with the physical (KYC) address I attempted to use. For this reason -- until finally adjusted by BofA (after first flat refusing the issue) -- I could not use my card at Delta because I could not figure out what address they believed they were verifying against. It took months for me to get them to believe it an issue and they claimed that KYC = billing address (which is of course false). I explain in more detail because the issue is with respect to lack of consistent definition. There is another further example of a bank confusing "mailing" address and "billing" address. In short, the bank verified against "billing" address but their database did not equate mailing=billing so the bank rejected the verification because no "billing" address was on file and there was a mismatch against KYC.

I believe that there is reason that all three -- with consistent definition -- may need to be part of the protocol because of the fluidity for people with various reasons to maintain a shipment location for goods and "letter" or USPS location for "billing". And both of these are not the KYC address because the merchant never has a reason to collect the actual KYC address. Help?

@djackso3
Copy link

@djackso3 djackso3 commented Apr 8, 2016

Before others say it -- there is a case that "shipping" address never enters the payments process and is only in the eCommerce flow. I can see this, however, I do see the continued confusion related to "billing", "mailing", "physical", "home", and other labels lacking consistency ... just an idea for consideration ...

@burdges
Copy link

@burdges burdges commented Apr 8, 2016

VAT rules in Europe get tricky, but :

  • If there is a shipping address, then shipping address, not billing address, that determines the VAT the merchant pays, so the merchant already knows this.
  • It's illegal to change the advertised price based on VAT recomputation, so the VAT rate cannot impact the payment directly.
  • If the merchant needs information from the PSP for their VAT payments, then they would probably prefer it as an end of year tax statement.
  • There are no requirements on Payment App, PSPs, etc. to provide any information. It true many do so, but sometimes as a tax statement, and sometimes as a paid tax related service.
  • Address capture increases the merchant's liabilities under the E.U. Data Protection Directive too, so the PSP to anonymizing data, or doing tax form for you, may actually have value over collecting the data yourself.

I think the fraud reasons @djackso3 highlights sound more critical than VAT since VAT rate cannot impact the sale. It's true some merchants could save money by processing this information themselves, assuming their PSP chooses to make it available.

A Payment App, PSP, etc. should never be forced to make this information available however. And they should not provide it unless the merchant actually requests it.

@halindrome
Copy link
Contributor

@halindrome halindrome commented Apr 8, 2016

VAT rules are quite different than the rules in the US. These vary by state, and within states by governmental district (county, city, etc.) Speaking as a merchant, I need to know a number of things about the purchaser to decide what sales tax to apply to the sale. But in general the rule is to use the shipping / use address to decide what sales tax to use, and then the billing address if a shipping / use address is not available. And yes, this does effect ultimate amount that is paid by the purchaser. Sales tax is passed on to the customer in the US in most cases.

@adrianhopebailie
Copy link
Collaborator

@adrianhopebailie adrianhopebailie commented Apr 10, 2016

We must distinguish between data that is required for processing the payment and data that is being requested to streamline the checkout flow.

@djackso3 said:

The method by which many payment systems work (especially in card) is to verify against billing address so billing address is required for some payment types and providers. In addition, some items will require the KYC address (government functions like BMV transactions).

Which implies that this data is required for payment processing and should be gathered by the payment app.

However, data that is required to calculate a final amount (i.e. it impacts the tax rate) should be supported as something that can be requested from the user agent so that the website has an opportunity to recalculate the final amount prior to the request being passed to the payment app.

@adrianhopebailie adrianhopebailie modified the milestones: Priority: High, Discuss on Call - 28 April, Discuss on Call - 5 May Apr 22, 2016
@adrianhopebailie adrianhopebailie modified the milestones: 12 May, 5 May May 12, 2016
@dlongley
Copy link

@dlongley dlongley commented May 12, 2016

The more things we keep trying to add the more I tend to think that a better design would be to provide new elements/components that merchants can put in their website to simply customize their checkout page. For example:

<shipping-address on-change="callme(event)"></shipping-address>

<billing-address on-change="callme(event)"></billing-address>

This component could be provided by the browser (or a polyfill), it could refuse to give access to the site (to JavaScript) any of choices shown to the user until one is selected, fire an "on address change" event when the user changes their address -- and let the merchant site customize their checkout experience around it. This would be a low-level component-based approach to providing a better checkout experience whilst also leveraging the browser's ability to provide this kind of information.

The idea that we're going to be able to specify every checkout flow (or "at least" the common ones) and do so in a sensible way I think is perhaps not as achievable as we'd like to think. When the checkout flow doesn't work for the merchant, they have to abandon the whole API and start from scratch. Wouldn't it be better to build out some components (that could also be polyfilled) that a merchant can use to assemble their own checkout experience?

With this approach they can configure it however they like -- update address/shipping options as they please and so forth, and still leverage the information that the user agent can provide to them. Then, once the final price has been calculated, they can call the payment request API with all of the requisite information they've collected to cause the user to select a payment app to complete the payment.

@ianbjacobs
Copy link
Collaborator Author

@ianbjacobs ianbjacobs commented May 12, 2016

-1 to including generic UI bits in the API. I think that will make it harder to gain adoption on the browser side.

Ian

@dlongley
Copy link

@dlongley dlongley commented May 12, 2016

@ianbjacobs,

I'm not a fan of the "all or nothing" design approach. What if we got to REC and didn't specify how to collect some piece of information that is required but the available choices are dependent upon some other piece of information we do collect via the API? Now that part of the API can't be sensibly used and has to be reimplemented on the merchant site.

Starting with a low-level design and providing higher-level options would avoid these scenarios and potentially increase adoption on the merchant side. It would also help browsers understand how merchants are putting the components together to build good checkout experiences -- which would be valuable data for them to use to improve their own higher-level options.

But I do agree that if browsers are disinterested in providing low-level components/APIs to merchants to allow them to construct better customized checkout experiences for more complex cases, this is a non-starter.

@adrianhopebailie adrianhopebailie modified the milestones: 12 May, 19 May May 18, 2016
@ianbjacobs
Copy link
Collaborator Author

@ianbjacobs ianbjacobs commented Jul 30, 2018

Yes, let's chat more this week.

Maybe no event is required. Could the merchant use retry() if the billing address affects the total?

Ian

@ianbjacobs
Copy link
Collaborator Author

@ianbjacobs ianbjacobs commented Aug 3, 2018

Hi all,

Here is some additional thinking about billing address and third party payment handlers.

  • Due to the nature of some payment methods (e.g., real-time financing, push payments), payment should not happen until after the "definitive" billing address is known to the payment handler.
  • Today we do not have a way for the payment handler to tell the merchant "here is the definitive billing address". Indeed, by design we don't have a way for the payment handler to interact with the merchant directly for any data updates.
  • Instead, updates happen in the sheet through user interaction. Events fire and the merchant can update the total, etc.
  • One approach is to say that the "definitive billing address" is the one provided by the user, before the payment handler is selected. The user might choose a billing address from a list stored by the browser. This would cause an event to fire and the merchant could update the total. Then the user could select the payment handler and the payment handler could receive the user-asserted billing address.
  • Once in the payment handler, if the billing address is correct, everybody is happy and payment can take place.
  • However, if the billing address differs from one known within the payment handler, we have an issue. One option is to allow the payment handler to ask the user to confirm a new billing address. If the user agrees, then fire an event to tell the merchant, which can update the total which is given to the payment handler.

One way to do this is through some sort of payment handler retry() mechanism, where the payment handler tells the browser (upon action by the user):

  • Close the payment handler window and return to the sheet
  • Ask the user to confirm the billing address (populated with the data from the payment handler)
  • If the user does, that triggers the onbillingaddresschange event and the merchant can update the total.
  • Then the user reselects the payment handler and starts again, this time with the proper billing address and total.

In other words: let's have all the data updates happen in the sheet so that the merchant can learn about them through events.

This would allow the payment handler to proceed to payment if it wants, or ask for a correction by the user (in the sheet) before proceeding to payment.

I realize this will be a non-pipeline user experience, and thus could potentially be confusing. I welcome suggestions for handling this in other ways, but I note that retry() from the merchant side is not likely to work in general because payment may have already happened (with a potentially incorrect total) by the time the merchant gets to do a retry().

There may also be some ways to simplify the user experience of getting the definitive billing address from the user:

  • If the merchant does not request billing address, there is no need to surface UX for it.

  • If the merchant does request billing address the browser does not have to surface UX for it initially.
    a) If the user chooses a card stored in the browser (which has associated billing address), there is no need to surface UX for choosing billing address; the event can fire with the card's billing address.
    b) If the user chooses a third party payment handler, the browser could (finally) surface UX to prompt the user to confirm or enter the billing address before launching the payment handler. There might be some options to make this smooth, such as choosing from among:

    • "Same as shipping address"
    • Choosing the most recently used billing address with that payment handler.
    • The ability to choose from among billing addressed stored with instruments in the browser.
    • Other manually added billing addresses.

    Once the billing address has been selected, the browser then launches the payment handler.

My "hope" is that the billing address is correct most of the time, and thus the "payment handler retry()" UX is not necessary often.

By the way, it has been pointed out to me that billing address information for tax purposes may also become a more important consideration in the US [1].

Ian
[1] https://www.nytimes.com/2018/06/21/us/politics/supreme-court-sales-taxes-internet-merchants.html

@marcoscaceres
Copy link
Member

@marcoscaceres marcoscaceres commented Aug 8, 2018

I'd like to exhaust @michelle's current proposal, which is #749. Honestly, the above sounds extremely complicated, and would like the various UX teams to explore how it might work best (the requirement is clear: "merchant needs the billing address to calculate, user want to protect their privacy until they hit pay" - let's leave it at that and lets explore how far we get).

@ianbjacobs
Copy link
Collaborator Author

@ianbjacobs ianbjacobs commented Aug 8, 2018

Hi @marcoscaceres,

I think one answer to "how far we can get" is "browser-stored cards." It is not clear to me from #749 how third party payment handlers would work.

Ian

@marcoscaceres
Copy link
Member

@marcoscaceres marcoscaceres commented Aug 8, 2018

Ok, but that’s a UX problem no? Or do we expect payment handlers to provide the billing address?

Put differently, we know that we want:

  1. Merchants to be able to request the billing address.
  2. When the user selects a billing address, the address is sent to the merchant so they can calculate tax.
  3. A means to update the total if needed (solved by ev.updateWith(), and retry()).

If the UA exclusively holds the billing address(es), then the above holds. If the payment handler holds the billing address, then we need to have a more detailed discussion... but it feels like that discussion is outside the scope of v1, personally.

@ianbjacobs
Copy link
Collaborator Author

@ianbjacobs ianbjacobs commented Aug 8, 2018

@marcoscaceres wrote:
"Or do we expect payment handlers to provide the billing address?"

Yes. My current understanding is that a payment instrument will have a billing address associated with it. For those payment instruments controlled by payment handler, they will therefore "own" the billing address.

@marcoscaceres wrote:
"If the payment handler holds the billing address, then we need to have a more detailed discussion...

Yes, that is why I included the detail above. I agree it's not simple at first glance.

@marcoscaceres wrote:
"but it feels like that discussion is outside the scope of v1, personally."

Perhaps. That should be an explicit decision of the group.

Ian

@marcoscaceres
Copy link
Member

@marcoscaceres marcoscaceres commented Aug 9, 2018

Yes. My current understanding is that a payment instrument will have a billing address associated with it. For those payment instruments controlled by payment handler, they will therefore "own" the billing address.

Ok, so, if billing addresses are bound to payment instruments, then paymentmethodchange might again be the right fit (as shown by Apple Pay).

Then a redacted address can be sent back with the event's methodDetails, allowing .updateWith() to be called. Similarly, then .retry() can be used when checking the PaymentResponse.

We can then work out what each dictionary looks like, but essentially, they can each have a PaymentAddress attached as needed, or sometimes null.

For each payment method, we can define a base dictionary that everyone could use:

dictionary PaymentMethod {
   PaymentAddress? billingAddress;
}

// for paymentmethodchange, for example:
dictionary BasicCardChangeDetails  : PaymentMethod {
   // inherits billingAddress;
}

dictionary BasicCardResponse  : PaymentMethod {
  // inherits billingAddress;
  // card number, etc.
}
@ianbjacobs
Copy link
Collaborator Author

@ianbjacobs ianbjacobs commented Aug 9, 2018

Hi @marcoscaceres,

I may not have understood your proposal fully. However, if the proposal anticipates that the merchant only receives a billing address after the payment handler has been launched, then I think the proposal will be inadequate for use cases where:

  • Payment happens within the payment handler (e.g., form sof push payment)
  • Agreements between the user and their PSP happen within the payment handler and likely depend on the total being accurate (e.g., real-time credit offers).

Ian

@marcoscaceres
Copy link
Member

@marcoscaceres marcoscaceres commented Aug 10, 2018

I’m going to defer this for a while until I can educate myself on those kinds of payments.

If there are some good resources on how push payments work, happy to have a read.

If we want to solve for basic-card and other card based payments, happy to continue on this.

@ianbjacobs
Copy link
Collaborator Author

@ianbjacobs ianbjacobs commented Aug 10, 2018

@rsolomakhin and I discussed this further today and I anticipate he will write up something sensible when time permits. At a high level, we discussed this type of flow which is a better experience than the one I had in mind.

  • The user has not yet selected a billing address.
  • The user selects a payment handler.
  • Within the payment handler, the user selects a payment instrument with associated billing address.
  • The payment handler informs the browser that the user has selected a billing address. The payment handler waits for a response (read: promise to resolve) that may update the total. The payment handler will not complete the transaction until hearing back from the merchant.
  • The browser fires the onpaymentmethodchange event to let the merchant know the billing address has changed.
  • The merchant responds with a (possibly null) update of the total.
  • The browser gives the (possibly updated) total back to the payment handler.
  • The payment handler displays the total and allows the user to proceed.

@marcoscaceres, regarding push v pull payments, here's a piece by Adrian Hope-Bailie:

A Push Payments Manifesto
https://adrian.hopebailie.com/a-push-payments-manifesto-2d8ff105f48a

Examples: wire payments, ACH payments, SEPA credit transfers, Boleto Bancário, bitcoin, various real-time payments systems, etc. I invite others who know more about payments to list some useful resources.

Ian

@adrianhopebailie
Copy link
Collaborator

@adrianhopebailie adrianhopebailie commented Aug 13, 2018

@marcoscaceres the key difference with push is that by the time the website gets the PaymentResponse the payment is complete.

You could even think of a payment method like PayPal as "push" in some contexts, in that:
the merchant calls PR API -> the user selects PayPal -> the user authorises the payment with PayPal -> the merchant gets back a PaymentResponse

Compared with BasicCard, for example, the merchant has nothing more to do but mark the sale asd complete. The payment is already done.

@marcoscaceres marcoscaceres removed their assignment Aug 14, 2018
@marcoscaceres
Copy link
Member

@marcoscaceres marcoscaceres commented Aug 14, 2018

@ianbjacobs:

@rsolomakhin and I discussed this further today and I anticipate he will write up something sensible when time permits. At a high level, we discussed this type of flow which is a better experience than the one I had in mind.

I don't understand how this is different from what I had proposed in the pull request? Could you please comment on the pull request? It seems like a waste of time for @rsolomakhin to have to redo what I already worked on? I don't see anything in your points that my pull request didn't already do.

The only difference from the points above is that there event was sent to the PaymentRequest (.onpayerdetailchange), instead of the onpaymentmethodchange, but that's just a detail.

Wrote @adrianhopebailie:

@marcoscaceres the key difference with push is that by the time the website gets the PaymentResponse the payment is complete.

Sure. I get that part.

Compared with BasicCard, for example, the merchant has nothing more to do but mark the sale as complete. The payment is already done.

I'm still not following :(

@marcoscaceres
Copy link
Member

@marcoscaceres marcoscaceres commented Aug 14, 2018

@adrianhopebailie just to be clear, when I say "I'm still not following :(", I mean I'm unsure what I should change in the pull request that I made to meet the use case. I need direct feedback on the pull request itself.

@adrianhopebailie
Copy link
Collaborator

@adrianhopebailie adrianhopebailie commented Aug 14, 2018

@marcoscaceres I don't think you need to change the PRs but perhaps there is a need to add something that shows how a PaymentHandler may cause the Payer address changed algorithm to be invoked (when a user provides a billing address through interaction with the PaymentHandler).

Q: Are you suggesting the spec text that describes how a Payment Handler might invoke the Payer address changed algorithm doesn't belong in the PaymentRequest but rather in the PaymentHandler spec?

Push Payments and retry()*

The underlying issue related to push payments is not with Billing Address but with retry(). It is too late to call retry() if the payment handler has already completed the payment. So, while a Billing Address issue may be one reason to call retry() it's not the root of the issue.

I don't think retry() is a good idea and I think what @ianbjacobs and @rsolomakhin are attempting to do is find a flow that avoids needing it.

@adrianhopebailie
Copy link
Collaborator

@adrianhopebailie adrianhopebailie commented Aug 14, 2018

@marcoscaceres @ianbjacobs @rsolomakhin I am throwing this idea in the ring: #759

because I think it would make solving this case a LOT easier.

@ianbjacobs
Copy link
Collaborator Author

@ianbjacobs ianbjacobs commented Aug 14, 2018

@adrianhopebailie and @marcoscaceres,

To help discussion around this issue I have started to catalog proposals (that I've heard) for handling push payments:
https://github.com/w3c/payment-request/wiki/PushPayments

Ian

@rsolomakhin
Copy link
Collaborator

@rsolomakhin rsolomakhin commented Aug 14, 2018

@marcoscaceres's pull request #749 for payer address looks good to me.

My discussion with @ianbjacobs concerned primarily figuring out how to make it work with payment handlers, which we have figured out, I believe, in a way compatible with #749.

Payment Handler discussion can get a bit complicated, so it's better to keep it on the Payment Handler page, IMHO. But let me break that rule myself already: @adrianhopebailie, for what it's worth, I believe a retry() would not make sense for push payments. The purpose of retry() is to correct data errors that prevented the merchant from initiating the transaction. Since the merchant is not in charge of initiating the transaction in push payment scenario, the retry() does not need to be used in that particular case.

@marcoscaceres
Copy link
Member

@marcoscaceres marcoscaceres commented Aug 28, 2018

So, I'm still worried about the whole billing address being tied to an instrument thing. For instance, I just bought a present for someone, and I obviously don't want to send the recipient the invoice. The website gave me these options:

screenshot 2018-08-28 15 53 45

It seems like this is not that uncommon. What am I missing?

@marcoscaceres
Copy link
Member

@marcoscaceres marcoscaceres commented Aug 28, 2018

(I guess the billing address is not used for invoicing but only for verification of the card)

@snez
Copy link

@snez snez commented Sep 10, 2018

Just adding a bit to the discussion - a billing address is really important when trying to perform any type of fraud prevention. When making a payment request, banks will compare the billing address to the real cardholder's address before declining a payment for fraud reasons.

Furthermore, many eCommerce platforms have been designed with a Billing Address as a minimum requirement for placing an order. Not providing a method to collect it makes the PaymentRequestAPI unsuitable for use on most major eCommerce platforms running on millions of websites.

Also for virtual/digital products, there is no shipping/delivery address, so you'd be inclined to skip the delivery address collection, however how is the merchant supposed to know the address of the customer if that is needed for any reason? This is usually why eCommerce platforms collect a billing address as a minimum, even for virtual products.

@marcoscaceres
Copy link
Member

@marcoscaceres marcoscaceres commented Nov 28, 2018

Closed by merging #27

PaymentAddress CTor automation moved this from To Do to Done Nov 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Linked pull requests

Successfully merging a pull request may close this issue.

You can’t perform that action at this time.