Ledger Innovation
Euvena

payto links for banking apps

For developers of banking apps · 26 September 2026

A payment request often reaches the payer on the phone they would pay with: an invoice in an email, a link in a chat, a QR code on a web page. The EPC QR code (“GiroCode”) needs a second device to scan it. On the same phone the payer copies the name, the IBAN, the amount and the reference into the banking app one by one.

A payto://iban link carries the same request as the code, in a form one app can hand to another. When your app accepts it, the payer taps the link and your transfer form opens filled in. The payer checks it and authorises it as usual. The scheme is RFC 8905; the payto handoff profile fixes how a SEPA credit transfer is written and read.

payto://iban/DE89370400440532013000?amount=EUR:25.00&receiver-name=Example%20Payee&message=Invoice%202026-001
  • iban/[BIC/]IBAN: the beneficiary's account, the BIC first when present
  • amount=EUR:25.00: the amount in euro, absent when the payer decides it
  • receiver-name: the beneficiary name, always present
  • message: the unstructured remittance information, up to 140 characters

1. Register the scheme

Android, on the activity that opens the transfer form:

<intent-filter>
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data android:scheme="payto" android:host="iban" />
</intent-filter>

iOS, in Info.plist:

<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLName</key>
    <string>payto</string>
    <key>CFBundleURLSchemes</key>
    <array><string>payto</string></array>
  </dict>
</array>

2. Read it strictly

Refuse the whole link when anything is wrong, and never fill in part of a transfer:

  • the IBAN passes its check digits and the BIC, when present, its format
  • the amount is EUR: and digits with a point, never a comma
  • receiver-name is present and not blank
  • no control characters, line breaks or bidirectional formatting characters in any value
  • an unknown option, a repeated option or an instruction refuses the link. The exceptions are sender-name, receiver-postal-code and receiver-town, which describe the parties rather than the payment and are ignored

In JavaScript or TypeScript, including React Native, @euvena/qr does this with decodePaytoUri. Kotlin and Swift versions are planned.

3. Show it before anything happens

  • Open the ordinary transfer form with the values filled in, showing the name, the full IBAN, the amount and the message.
  • Authorise exactly as for a transfer the payer typed in, with no step skipped. Any app on the phone can open a link.
  • Run your usual checks, including Verification of Payee.
  • Let the payer choose the account to pay from. The link never names it.

Open this page on a phone with your build installed and tap each link. The account is the widely published example IBAN, which may still belong to someone, so stop at the filled-in form and do not authorise. Use your own test account for an end-to-end run.

More

The full guide and the Euvena repository, where the Euvena wallet emits these links. Questions and reports of apps that accept them are welcome in the issue tracker.