stellar / stellar-protocol

Developer discussion about possible changes to the protocol.
515 stars 302 forks source link

SEP-0009 international payment fields #152

Closed paultiplady closed 5 years ago

paultiplady commented 6 years ago

Moving discussion from https://github.com/stellar/stellar-protocol/pull/136#issuecomment-414441903:

In SEP-9, we have the fields:

bank_account_number | Number identifying bank account
bank_number | Number identifying bank (routing number in US)

I'm a little concerned that the bank_number field won't be workable for global payments -- for example, in many countries, there are a number of different "bank numbers"; e.g. to pay someone in India, it might be:

SWIFT (if you're sending them a wire) IFSC INRN

Or a less esoteric example, to get to the UK it might be:

SWIFT Sort code IBAN (this actually includes bank number and account number)

Additionally, the anchor might only be able to process a subset of the bank number types, e.g. only supporting wire to the UK, even though a local would naturally provide "sort code" in this case.

The international payments API that my system uses is (unfortunately) quite complex, and the required fields are dependent on what country the beneficiary is located in. (This is quite standard for international payment rails, in my experience).

Not to mention that certain countries require additional regulatory information such as patronymic name in Russia (in addition to first/last), or CPF codes in Brazil. (An even bigger can of worms).

In summary, I think there are a few open questions here:

  1. How can we support specifying which payment methods (and therefore which bank_number types) an anchor supports?
  2. How can we annotate which bank_number type is being sent?
  3. How can we specify regulatory information that is required on a per-country basis?
  4. How do we handle changing regulatory field requirements? Should we add support for freeform/dynamic fields in addition to drawing from the fixed field names in SEP-9?

CC @tomquisel

tomquisel commented 6 years ago

@paultiplady these are great points.

The fact that the required fields are dependent on the country makes it impractical to define all the possible fields in a global SEP like SEP-9.

This kind of situation, where an anchor needs to communicate which kinds of bank number types it supports for deposits and withdrawals, should be handled by SEP-6. An anchor can broadcast its capabilities with /info, and the specific kind of bank number or deposit / withdrawal method for a particular transaction can be specified by the client passing type to deposit or withdrawal.

That should handle open questions 1 & 2.

As far as per-country regulatory information, the goal of SEP-9 is to cover the ~80% of most common use cases. We can add fields as they're needed for more major use cases. Any fields that are more rare should be handled with an interactive flow provided by the anchor instead.

As far as changing regulatory requirements, SEP-9 aims to allow a wallet or other client app to collect information from a user once, and then reuse that information multiple times as the user performs KYC with different anchors. If we add dynamic fields, there's no way to reuse them. A wallet can't be sure that a dynamic field called "cpf_code" for anchor A is the same as for anchor B, even if the names match. That's why SEP-9 is hard coded. That said, as regulations change, SEP-9 should be updated to include new fields.

Dynamic fields should just be handled by one-off KYC flows provided by anchors, since they can't be re-used by the wallet with other anchors.

Please feel free to suggest a list of fields that would be useful for you (patronymic name, CPF code, etc...) and we'll merge those in to get you going.

paultiplady commented 5 years ago

Thanks, that clarification is useful -- so for countries with regulatory requirements the solution is just to defer to the interactive flow in the anchor's UI. That actually works fine, in my experience the extra regulatory fields only apply to 10-20 countries in the world, definitely in the long tail of payment volume.

I'm wondering though, how would you expect the anchor to communicate e.g. ACH vs. wire for a US payment in the 2. Customer information needed (non-interactive) flow? I don't see how that flow can work at all, given that bank_number is fundamentally ambiguous. It seems that the client would need to parse the /info and see that it says

{
  "withdraw": {
    "USD": {
      "types": {
        "bank_account": {
          "fields": {
              ...
              "dest_extra": { "description": "your routing number" },
...

Instead of "your SWIFT number". If those fields are freeform text, it's going to be difficult to reliably differentiate between the two.

If we define "bank_number" to mean "bank number in the national banking system" that will cover most countries unambiguously (though e.g. India does have multiple national bank codes), and extra fields for "swift_code" and "iban" would cover the international bank identifiers used in most countries.

I'm not currently blocked on this by the way -- my use-case is USD-specific for now. Just raising as I went through the exercise of thinking through how I'd map my existing international payments onto this flow.

tomquisel commented 5 years ago

Good questions @paultiplady.

This PR clarifies an anchor communicating ACH vs. wire for a deposit.

Here are the steps:

That doesn't involve SEP-9, which is more for KYC / AML. bank_number is included there since it can be a piece of information about a person that's used for KYC, but it's not necessarily the same as the account used for deposit / withdrawal.

That said, I'll update SEP-9 to improve the definition of bank_number like you suggest. Thanks so much for your thoughts!

tomquisel commented 5 years ago

PR: #163

theaeolianmachine commented 5 years ago

Closed by #163. Thanks @paultiplady!