How to Integrate Interac e-Transfer into Your Mobile App
Integrating Interac e-Transfer into your mobile app means connecting to a payment API provider that supports e-Transfer rails, then building the payment flows, callback handling, and user notifications into your iOS or Android codebase. You do not connect to Interac directly. Instead, you work through a FINTRAC-registered payment provider like Invincible Pay, which gives you a REST API to initiate, track, and receive e-Transfers programmatically.
If you are building a Canadian mobile app and want to let users send or receive money instantly, this guide walks you through the full integration, from choosing an API provider to handling deep links and push notifications for payment status updates.
Why Should You Add Interac e-Transfer to Your Mobile App?
Interac e-Transfer is the most widely used digital money transfer method in Canada. According to Interac Corp, the platform processes millions of transactions every day. Three out of four Canadians regularly use it to send or receive money. For app developers and product teams, that level of adoption makes e-Transfer one of the easiest payment methods to offer because your users already know how it works.
Adding e-Transfer to your mobile app also comes with practical advantages over card-based payments. Transaction fees are significantly lower, often up to 80% cheaper than credit card processing. Settlement is near instant, with most transfers completing in minutes rather than days. And because e-Transfer works directly between bank accounts, there are no chargebacks to worry about.
For businesses processing higher-value transactions, e-Transfer supports up to $25,000 per transaction through providers like Invincible Pay, compared to the $3,000 cap most traditional banks impose on personal e-Transfers. That higher limit opens up use cases like real estate deposits, contractor payments, invoice settlement, and B2B transactions that would otherwise require wire transfers.
How Does e-Transfer API Integration Work at a High Level?
Before diving into the technical steps, it helps to understand the overall architecture. Here is how the pieces fit together.
Interested in modern payment tools?
Get started in minutes. FINTRAC registered. Bank of Canada regulated.
Your mobile app does not connect to Interac's network directly. Interac e-Transfer is a closed network available only to participating financial institutions. As a developer, you integrate through a payment service provider (PSP) that has established connectivity to the Interac network. The PSP provides you with a REST API, webhooks, and a sandbox environment for testing.
The typical payment flow looks like this. Your app sends a request to the PSP's API with the recipient's email or phone number and the amount. The PSP initiates the e-Transfer through the Interac network. The recipient receives an email or SMS notification from Interac. They deposit the funds through their own bank. Your PSP notifies your app via a webhook that the transfer has been completed (or rejected, or expired).
For inbound payments (receiving money from your users), the flow reverses. Your app generates a payment request through the API, the user completes it through their bank, and your PSP confirms receipt via webhook.
How Do You Choose the Right e-Transfer API Provider?
Not all payment providers offer the same capabilities, so choosing the right one matters. Here are the key factors to evaluate.
Transaction limits and volume capacity. If your app needs to handle large payments, you need a provider that supports higher per-transaction limits. Invincible Pay supports e-Transfers up to $25,000 per transaction with no daily caps, which is critical for apps serving freelancers, small businesses, or B2B marketplaces.
API design and documentation. Look for a clean REST API with comprehensive docs, a sandbox environment, and clear error codes. You want well-documented endpoints for initiating transfers, checking status, and handling webhooks. Invincible Pay provides a full REST API built for developers, with detailed documentation and sandbox access for testing before you go live.
Compliance and regulation. Your provider must be FINTRAC-registered and compliant with Canadian AML (anti-money laundering) regulations. This is non-negotiable. Working with a regulated provider means you inherit their compliance infrastructure rather than having to build your own KYC/AML pipeline from scratch. Invincible Pay is FINTRAC-registered and regulated by the Bank of Canada under the RPAA, with funds safeguarded at Schedule 1 Canadian banks.
Onboarding speed. Some providers take weeks to approve new integrations. Others, like Invincible Pay, offer onboarding in as little as five minutes with a fully digital KYC process.
Support for both send and receive flows. Make sure the API supports both disbursements (sending money out) and collections (receiving money in). Some providers only support one direction.
What Are the Technical Steps to Integrate e-Transfer into Your App?
Here is a step-by-step walkthrough of the integration process, written for iOS and Android developers working with a REST API.
Step 1: Set Up Your API Credentials
After registering with your payment provider, you will receive an API key (or client ID and secret pair) and access to a sandbox environment. Store your credentials securely using your platform's keychain or encrypted storage. Never hardcode API keys in your mobile app binary.
For server-side calls (which is the recommended approach), your backend server holds the API credentials and acts as a proxy between your mobile app and the PSP. This keeps your keys out of the client-side code entirely.
Step 2: Build the Payment Initiation Flow
When a user wants to send money through your app, your mobile client sends a request to your backend, which then calls the PSP's API. A typical request body looks something like this (exact field names vary by provider):
{
"amount": 1500.00,
"currency": "CAD",
"recipient_email": "recipient@example.com",
"recipient_name": "Jane Smith",
"memo": "Invoice #1234",
"callback_url": "https://yourapp.com/api/etransfer/callback"
}Your backend validates the request, adds authentication headers, and forwards it to the PSP. The PSP returns a transaction ID and status, which you store in your database and relay back to the mobile client.
Step 3: Handle the Redirect Flow (If Applicable)
Some e-Transfer flows involve redirecting the user to their bank's online portal to authorize the payment. In this case, your PSP returns a redirect URL. On mobile, you have two options for handling this.
The first option is to open the URL in an in-app browser (using SFSafariViewController on iOS or Chrome Custom Tabs on Android). This keeps the user within your app's context and provides a cleaner experience than launching an external browser.
The second option is to use a system browser intent. This is simpler to implement but creates a more disjointed user experience because the user leaves your app entirely.
After the user completes the bank authorization, the bank redirects them back to your app using a callback URL. This is where deep linking becomes essential.
Step 4: Implement Deep Linking for Payment Callbacks
Deep linking lets you bring the user back to a specific screen in your app after they complete a payment action in their bank's portal. Without deep links, the user would land on your app's home screen and have no idea whether the payment went through.
On iOS, register a custom URL scheme (e.g., yourapp://) or set up Universal Links with an associated domain. Universal Links are the preferred approach because they are more secure and work even when the app is not installed (falling back to your website).
In your AppDelegate or SceneDelegate, handle the incoming URL:
func application(_ app: UIApplication, open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if url.host == "payment-complete" {
let transactionId = url.queryParameters["txn_id"]
// Navigate to transaction confirmation screen
return true
}
return false
}On Android, add an intent filter in your AndroidManifest.xml:
<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="yourapp" android:host="payment-complete" />
</intent-filter>Then handle the incoming intent in your Activity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val data = intent?.data
if (data?.host == "payment-complete") {
val transactionId = data.getQueryParameter("txn_id")
// Navigate to confirmation screen
}
}The deep link URL that you provide to your PSP as a callback might look like yourapp://payment-complete?txn_id=abc123&status=success. When the bank redirect completes, the user is sent to this URL, which opens your app and lands them on the right screen.
Step 5: Set Up Webhooks for Server-Side Status Updates
Deep links handle the client-side redirect, but you also need server-side confirmation that the payment actually went through. This is where webhooks come in.
Your PSP will send HTTP POST requests to your callback URL whenever a transaction status changes (e.g., pending, completed, failed, expired). Your backend should:
Verify the webhook signature to confirm it came from your PSP (not a spoofed request).
Parse the transaction ID and new status from the payload.
Update the transaction record in your database.
Trigger a push notification to the user's device.
Always respond to webhooks with a 200 status code quickly. Do your processing asynchronously so you do not hit timeout limits.
Step 6: Add Push Notifications for Payment Status
Push notifications keep your users informed about payment progress without requiring them to open the app and check manually. Combined with deep links, they create a smooth end-to-end experience.
Here are the key notification triggers to implement:
Payment sent. Confirm to the sender that the e-Transfer has been initiated. Example: "Your $1,500.00 e-Transfer to Jane Smith has been sent."
Payment deposited. Notify the sender when the recipient has deposited the funds. Example: "Jane Smith has deposited your $1,500.00 e-Transfer."
Payment received. If your app supports inbound payments, notify the recipient when funds arrive. Example: "You received a $500.00 e-Transfer from John Doe."
Payment failed or expired. Alert the user if something goes wrong so they can retry. Example: "Your e-Transfer to Jane Smith has expired. The funds have been returned to your account."
When the user taps any of these notifications, deep link them to the transaction detail screen rather than the app's home page. This saves them from having to hunt for the transaction in their history.
On iOS, use APNs (Apple Push Notification service) with the userInfo dictionary to pass the deep link:
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
if let deepLink = userInfo["deep_link"] as? String,
let url = URL(string: deepLink) {
// Navigate to transaction detail screen
}
completionHandler()
}On Android, include the deep link as an extra in the notification intent and handle it in your Activity's onCreate or onNewIntent.
What UX Best Practices Should You Follow?
Technical integration is only half the job. If the payment experience feels clunky or confusing, users will abandon it. Here are the UX patterns that matter most.
Keep the Payment Form Simple
Only ask for the information the API requires. For most e-Transfer flows, that means the recipient's name, email address (or phone number), the amount, and an optional memo. Do not add extra fields unless they are genuinely necessary.
Pre-populate fields where you can. If the user has sent money to this recipient before, auto-fill their details. If the user's account has a default funding source, do not make them select it every time.
Show Real-Time Transaction Status
Users want to know what is happening with their money at every step. Display a clear transaction status on the confirmation screen, and update it in real time as webhooks arrive. A simple status timeline works well:
Initiated (the request was sent to the PSP)
Sent (the e-Transfer notification was delivered to the recipient)
Deposited (the recipient has claimed the funds)
Use colour coding or iconography to make the current status immediately scannable.
Handle Errors Gracefully
Payment errors are inevitable. Your app should handle them without causing panic. If the API returns a validation error (e.g., invalid email format), show a clear inline message next to the offending field. If the transfer fails on the backend, explain what happened in plain language and offer a retry option. Never show raw API error codes to users.
Support Both Light and Dark Mode
This is a small detail that signals quality. Make sure your payment screens render properly in both light and dark mode, especially status indicators and success/failure states.
Consider Accessibility
Payment screens should be fully accessible. Use semantic labels for screen readers, ensure sufficient colour contrast on status indicators, and make all interactive elements large enough for comfortable tap targets (at least 44x44 points on iOS, 48x48 dp on Android).
How Do You Handle Security and Compliance?
Security is not optional when you are handling money movement. Here are the baseline requirements.
Use HTTPS for all API calls. Never send payment data over an unencrypted connection. Pin your SSL certificates to prevent man-in-the-middle attacks.
Validate webhook signatures. Every webhook from your PSP should include a signature header. Verify it against your shared secret before processing the payload. This prevents attackers from sending fake status updates to your server.
Never store sensitive banking data in your app. Your PSP handles the connection to the banking network. Your app should only store transaction IDs and status information, not bank account numbers or login credentials.
Implement session timeouts and biometric authentication. For payment screens, require the user to re-authenticate if they have been idle for more than a few minutes. Support biometric authentication (Face ID, Touch ID, fingerprint) for a balance of security and convenience.
Follow FINTRAC requirements. If your app facilitates money transfers, you may need to register as an MSB yourself or operate under the umbrella of a registered provider. Working with a FINTRAC-registered provider like Invincible Pay simplifies this because they handle the regulatory compliance on your behalf, including 24/7 fraud monitoring and KYC verification.
What About Testing and Going Live?
Sandbox Testing
Your PSP's sandbox environment lets you simulate the full payment flow without moving real money. Test for these scenarios at a minimum:
Successful send and deposit
Recipient email not found or invalid
Transfer expired (recipient did not deposit in time)
Duplicate transaction attempts
Webhook delivery failure and retry
Deep link callback with missing or malformed parameters
Staged Rollout
Once sandbox testing is solid, do a staged rollout. Start with a small group of internal users, then expand to a beta group, then go fully live. Monitor your webhook processing, push notification delivery rates, and error logs closely during each phase.
Monitoring in Production
Set up alerting for failed API calls, webhook processing errors, and any transactions that stay in a "pending" state for longer than expected. Track key metrics like transfer completion rate, average time to deposit, and error rate by type.
FAQ
Can I connect my mobile app directly to Interac's e-Transfer network?
No. Interac e-Transfer is a closed network available only to participating financial institutions. To add e-Transfer to your app, you integrate through a payment service provider like Invincible Pay, which has an established connection to the Interac network and provides you with a developer-friendly REST API.
What are the transaction limits for e-Transfer through an API?
Limits depend on your provider. Most traditional banks cap personal e-Transfers at $3,000 per transaction. Invincible Pay supports up to $25,000 per transaction with no daily limits, which makes it suitable for business, freelancer, and marketplace applications.
Do I need to be a registered MSB to offer e-Transfer in my app?
If your app facilitates the transfer of money, you may need to register with FINTRAC as a money service business. However, by integrating through a FINTRAC-registered provider like Invincible Pay, the provider handles the bulk of the regulatory compliance, including KYC, AML monitoring, and transaction reporting.
How long does an e-Transfer take to complete?
Most e-Transfers are completed within minutes once the recipient deposits the funds. The initiation is near-instant on the sending side. Total end-to-end time depends on how quickly the recipient acts, but funds are typically available within 30 minutes of deposit.
What happens if an e-Transfer fails or expires?
If a recipient does not deposit the funds within the expiry window (typically 30 days), the transfer is cancelled and the funds are returned to the sender's account. Your app should handle this gracefully by notifying the user via push notification and updating the transaction status in the UI.
Ready to add e-Transfer to your mobile app? Invincible Pay gives you a full REST API, $25,000 transaction limits, and five-minute onboarding. Talk to our team or open your Invincible Wallet to get started.
