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

Add structured ISO-11649 creditor references for EUR bank transactions #1292

Merged
49 commits merged into from
Mar 1, 2024

Conversation

jayaddison
Copy link
Contributor

@jayaddison jayaddison commented Dec 17, 2023

The lack of structured ISO-11649 creditor references seems to be at least one potential/likely reason why many SEPA-QR enabled banking applications failed to parse our QR codes during testing in #875.

There are a few more todos here:

  • Determine whether to use Payment.id (sequence) or BankPayment.bankref to derive the creditor reference. (answer: prefer bankref; it is already a subset of the base36 charset available for use with ISO-11649, and is randomised, which is probably a property that's better to keep than to discard)
  • Ensure that this works correctly end-to-end including reconcilation of transactions after receiving Wise balance credit webhooks.
  • Re-test using SEPA QR scanner apps. (results: testing of commit 1cc7342 seems good. two apps (Nordea, Deutsche Bank) are now able to scan the codes correctly)
  • Hide the QR image by default in the bank-transfer template; expand that on-click, and provide an info/help icon with a hover-over explanation text alongside (regardless of expanded/collapsed state).

Resolves #878.

@jayaddison
Copy link
Contributor Author

Either here or in a follow-up PR: adding the amount, recipient name, creditor reference and IBAN in plaintext on the edges of the SEPA QR for additional human verification and reassurance purposes

It seems that most of the relevant details (IBAN, recipient name, reference) are displayed in close proximity to the EPC QR already -- so maybe we don't need this.

However we should display the full creditor reference in relevant invoices -- not only the shorter 8-char bankref value.

The formatting helper that we use when displaying bankrefs in invoices would reformat, for example, a creditor reference of RF67E9HKFVR8Q as RF67-E9HKFVR8Q - not a terrible display format, but perhaps we could improve upon that.

…imit the structured creditor reference from the bankref; this should allow existing transaction-matching logic to function as-is"

This reverts commit 5d30c7e.
@jayaddison

This comment was marked as resolved.

@marksteward
Copy link
Member

marksteward commented Dec 18, 2023

safechars (which is the Microsoft product key character set) doesn't have any vowels to reduce the chance of coming up with pronounceable words. But the reason it's short and dense is to allow manual entry and to round-trip through old bank systems that don't support separate references. Do we still have that problem with ISO-11649? Do Barclays still end up concatenating the account name and reference?

I feel like we should keep bankref separate from creditor reference, and change the label to something like "reference for manual entry". We could show the creditor reference for EUR payments, to prevent people wondering where it is, but I don't see why it shouldn't basically be the invoice number.

If that's going to lead to more confusion (I don't know what the various EU bank payment forms might look like), we can just exclude R and F from the start of the bankref, i.e. change this to:

"".join(random.sample(safechars.replace("R", "").replace("F", ""), 1) + random.sample(safechars, 7))

This should probably be random.choices too.

@marksteward
Copy link
Member

FWIW, I've played around with generating EPC codes at https://www.qr-code-generator.com/solutions/epc-qr-code/ and the Revolut app ignores the IBAN for GB, because it switches the form to sort code/account number mode.

I'm a bit concerned this might be why other apps aren't processing the QR codes, and we might be setting ourselves up for more of a headache than it's worth.

@russss
Copy link
Member

russss commented Dec 18, 2023

We don't use Barclays any more, and at any rate SEPA references have significantly longer field limit than BACS references, so length isn't an issue.

@jayaddison

This comment was marked as resolved.

@jayaddison

This comment was marked as outdated.

@jayaddison

This comment was marked as outdated.

@jayaddison

This comment was marked as resolved.

… headers

Accompanying test coverage is provided, and in particular this intends to demonstrate that the string 'RF' followed by two digits is valid _within_ generated references.
@jayaddison jayaddison marked this pull request as ready for review December 18, 2023 16:55
@jayaddison jayaddison changed the title WIP: Add structured ISO-11649 creditor references for SEPA QR codes Add structured ISO-11649 creditor references for SEPA QR codes Dec 18, 2023
@russss russss marked this pull request as draft December 22, 2023 12:12
@jayaddison
Copy link
Contributor Author

A recording of the recently-added EPC QR explainer tooltip in action:

epc-qr-explainer.webm

@jayaddison jayaddison marked this pull request as ready for review January 8, 2024 22:30
@russss
Copy link
Member

russss commented Feb 21, 2024

We had a report that our payment reference didn't work when sending a payment from a Dutch bank, because it was expecting a reference in a standard format. (I think it's likely that there was a separate description field where our reference would have worked, but this proved a useful test case.)

I manually generated an ISO-11649 reference (RF82FTHGBVX2) and the payer successfully used that. We just got the payment and the incoming reference received in Wise was RF82FTHGBVX2/20240221220607<IBAN> (where <IBAN> is the payer's IBAN).

So that has conveniently validated whether this works on the banking side - although the reference does come through in a slightly interesting format, which wasn't auto-reconciled currently.

I was previously a little concerned about how this would work in practice, but I'm fairly happy now that we should move to using ISO-11649 references, at least for Euro payments.

@jayaddison
Copy link
Contributor Author

Thanks @russss - that's great to have confirmed.

To handle the additional reference-format encountered: perhaps we could check whether the ref up-to-a-/-delimiter is a valid ISO11649 reference (using python-stdnum), and if so omit the remainder of the string from the matching process?

@russss
Copy link
Member

russss commented Feb 22, 2024

I wouldn't guarantee that the format will always be the same, although I'd hope it's the case, so I think we should still assume that it can appear anywhere in the reference field.

I have a few more comments which I'll put inline, but I'm inclined to get this merged soonish now.

models/payment.py Outdated Show resolved Hide resolved
models/payment.py Outdated Show resolved Hide resolved
@jayaddison jayaddison changed the title Add structured ISO-11649 creditor references for SEPA QR codes Add structured ISO-11649 creditor references Feb 25, 2024
@jayaddison jayaddison changed the title Add structured ISO-11649 creditor references Add structured ISO-11649 creditor references for EUR bank transactions Feb 25, 2024
@marksteward marksteward closed this pull request by merging all changes into main in 4421062 Mar 1, 2024
@marksteward marksteward deleted the issue-878/eur-bank-transfer-iso-11649-references branch March 1, 2024 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SEPA payment references should be ISO 11649 Creditor References
3 participants