Migrating End Customers
Migrating your end customer base from one bank to another can be a complex process. It involves compliance and regulatory aspects, as well as product and technology builds, and end customer experience considerations.
Unit supports two types of migrations:
- Fintech programs that migrate to the Unit platform from an external, existing bank relationship
- Migrations from one Unit partner bank to another.
This guide addresses migrations within the Unit ecosystem.
These migrations are significantly simpler then typical bank migrations:
- Before and after the migration, you would be using the same technology stack.
- Your support and operations teams would be using the same dashboard, processes and tools.
- The KYC/KYB requirements vary by Bank Partner, but typically completed KYC/KYB will be honored for a migration. Individual Client cases may vary and will be worked through in collaboration with the BSA team and the new Bank Partner. The existing customerId can be used to create accounts on the new Bank Partner.
- You do not have to build the end customer experience, create the new accounts and cards, or move the funds - Unit's new white label migration product will deal with that for you, in a secure, compliant and customer-friendly manner.
Overview
Migrating from one bank partner to another is a multi step process. At a high level, it includes the following:
- Creating a relationship with the new partner bank and configuring new deposit products at this new partner bank within Unit.
- Onboarding all net new end customers to the new bank relationship.
- Migrating existing customers to the new bank (creating accounts, issuing cards, closing old accounts, transferring balances).
White-Label Migration Product
The white label migration product offers an end-to-end migration process fully managed by Unit. You will be able to initiate a migration for every end customer with an open account and a non-negative balance. Customers with negative balances have to top-up their account before initiating the migration process.
The image below provides a high level overview of the migration process. The specifics of the process are not final and are subject to bank approval.
White label emails and experiences:
Emails:
Unit will send emails to the end customers on your behalf, to their email address on file. The emails will be sent from your email domain, and will have your branding applied to them.
- Invitation to migrate to the new bank, including a link to the white label migration experience.
- Reminder emails with a link to the white label migration experience will be sent every week if customers do not accept the migration invitation or the deadline date arrives.
- Account closure notification (30 days before account closure). The formal email informing the customer of the account closure procedure.
- ACH transfer confirmation for each money movement from old account(s) to new account(s), such as outstanding balance transfer.
White Label Experiences:
The white label experiences use Unit's White-label component infrastructure, and support deep white labeling. These experiences will be web pages, hosted by Unit, but will be white-labeled to your domain, so the URL presented will be your company's URL. The email outreach mentioned above will include secure links to those experiences. Once the customer clicks any link to a white-label experience, we will verify their identity through a one-time-password sent to their phone number on file (for business customers, it will be sent to the business contact).
The image below provides a high level preview of the end customer migration experience. The experience is not final, and is subject to minor changes and bank approval.
Implementation
Setup
Set up White-Label Outreach. Follow all steps outlined to set up white label outreach.
APIs
Create
For every customer you wish to migrate, you would need to call the migrations API. Once you do, the migration process will begin. You will be updated on the progress via standard webhook events such as account.created, card.statusChanged, card.created, payment.created and more events will be added later. You will also get a periodic report from your CSM on the progress (In later versions, you will have a migrations screen in the Unit dashboard).
The migration process will create the same setup of accounts the customer currently has, including deposit products, cards and tags.
- New accounts will have the same account number as the original accounts, but a different routing numbers
- Virtual cards will be reissued and will immediately be available and active.
- Physical cards will be shipped, and will take 7-10 business days to arrive.
- By default, Unit will initiate the transfer of funds as soon as the customer consents. Funds should be available on the next banking day (depending on the time of the user consent, it might be after the bank cutoff which means it will take 2 banking days).
- It is also possible to configure the migration to transfer the funds on the migration deadline. Please contact Unit if you want to use this functionality.
Request:
curl -X POST 'https://api.s.unit.sh/migrations' \
--H 'Content-Type: application/vnd.api+json' \
--H 'Authorization: Bearer ${TOKEN}' \
--data '{
"data": {
"type": "customerBankMigration",
"attributes": {
"fromBank": "ABC",
"toBank": "XYZ bank",
"idempotencyKey": "3a1a33be-4e12-4603-9ed0-820922389fb8",
"deadline": "YYYY-MM-DD"
},
"relationships": {
"customer": {
"data": {
"type": "customer",
"id": "10002"
}
},
"whiteLabelTheme": {
"data": {
"type": "whiteLabelTheme",
"id": "10002"
}
},
"outreachSettings": {
"data": {
"type": "outreachSettings",
"id": "10000"
}
}
}
}
}'
{
"data": {
"type": "customerBankMigration",
"id": "10001",
"attributes": {
"status": "CollectingAccountsConsent",
"deadline": "2024-06-30",
"fromBank": "ABC",
"toBank": "XYZ bank",
"orgName": "Your Org",
"supportEmail": "support@your-domain.co",
"supportPhone": "support phone nubmer",
"migrationUrl": "http://<your_domain>/DB2Y3CNSVWMN4U6FIVWR4BZ375R2WUEM4CY32C3CYGGICFJPMWDRYF3MKXKB2TXWSWUNH63T3BTSUWDOZCUCMGMLYWSCFC33NOFJT42KS6UADGQOJOHWME2J372JEXIXMBAZU3HYYCXP324PXWUJD272EGC6G",
"createdAt": "2024-05-07T12:02:35.624Z",
"updatedAt": "2024-05-07T12:02:36.064Z"
},
"relationships": {
"customer": {
"data": {
"type": "customer",
"id": "10002"
}
},
"whiteLabelTheme": {
"data": {
"type": "whiteLabelTheme",
"id": "10002"
}
},
"outreachSettings": {
"data": {
"type": "outreachSettings",
"id": "10000"
}
}
}
}
}
Attributes
Name | Type | Description |
---|---|---|
fromBank | string | Required. The name of the bank you are migrating from |
toBank | string | Required. The name of the bank you are migrating to |
idempotencyKey | string | Required. See Idempotency. |
deadLine | RFC3339 Date string | Date only (e.g. "2001-08-15" ). the date the existing accounts on the old bank will be closed |
suppressInvitationEmail | boolean | Optional. If set to true, the invitation email will not be sent to the customer. Default is false. |
digitallyActivatePhysicalCards | boolean | Optional. If set to true, the physical cards will be activated digitally. Default is false. |
balanceTransferTiming | NewAccountCreation / MigrationDeadline | Optional. The timing of the balance transfer. Default is "NewAccountCreation". Please contact Unit if you want to use this attribute. |
Exceptions
Migration will not be initiated after POST request and will return an error in case:
- Setup is not done
- Parameters in POST request are erroneous
- Migration deadline is less than in 30 days after Migration POST date
- Migration has already started
- One or more Customer accounts have negative balance
- Customer has open credit accounts
Reset Migration
The migration request can succeed, but result in an IneligibleCustomer
status.
This can happen if the customer has account(s) negative balance, frozen account(s), or joint account(s).
In such cases, the migration can be reset and retried, after the issue is resolved.
Request:
curl -X POST 'https://api.s.unit.sh/migrations/10001/reset' \
--H 'Content-Type: application/vnd.api+json' \
--H 'Authorization: Bearer ${TOKEN}' \
Response:
Find Migrations
Request:
curl -X GET 'https://api.s.unit.sh/migrations' \
--H 'Authorization: Bearer ${TOKEN}'
Query Parameters
Name | Type | Default | Description |
---|---|---|---|
filter[status][] | string | (empty) | Optional. Filter Migrations by Migration Status. Usage example: filter[status][0]=CollectingMoneyMovementConsent&filter[status][1]=CollectingAccountsConsent |
filter[customerId] | string | (empty) | Optional. Filter Migrations by customer id. |
Response:
Array of Migration Response
Migration Lifecycle
The Migration resource will move through the following statuses:
MigrationStarted - a new Migration initiated and a new Migration resource created, with corresponding attributes.
CollectingAccountsConsent - expecting Customer to consent to start program with the new Bank
MigratingAccounts - consents collected, creating account(s) and card(s) in the new bank.
- When new account process will be completed regular webhook event of account.created will be fired. In addition, account.migrated webhook event will be fired.
CollectingMoneyMovementConsent - new account(s) and card(s) created, expecting Customer’s consent to allow funds movement from old account(s) to new account(s) going forward
When
balanceTransferTiming
is set toNewAccountCreation
:ExecutingMoneyMovement - consent received, the outstanding balance transferred
PendingMigrationDeadline - pending the deadline date. The balance movement job will run on a daily basis to ACH any outstanding balance that will appear on old account(s) to new account(s). For each ACH performed, Customer will receive the ACH confirmation notification.
When
balanceTransferTiming
is set toMigrationDeadline
:PendingMoneyMovementOnDeadline - pending the deadline date. The balance movement job will not handle those migration until the deadline date. Once the deadline is reached the balance movement job will ACH outstanding balance from old account(s) to new account(s), customer will receive ACH confirmation notification.
ExecutingMoneyMovement - deadline exceeded, the outstanding balance transferred
ClosingAccounts - on the deadline the old accounts will be closed by the Migration deadline job
Completed - old accounts closure completed, Migration completed
Migration Webhook Events
migration.created
Occurs when a Migration resource is created succesfully.
{
"data": [
{
"id": "3323",
"type": "migration.created",
"attributes": {
"createdAt": "2024-05-23T06:56:22.247Z",
"status": "CollectingAccountsConsent"
},
"relationships": {
"migration": {
"data": {
"id": "10047",
"type": "customerBankMigration"
}
},
"customer": {
"data": {
"id": "10064",
"type": "customer"
}
}
}
}
]
}
migration.statusChanged
Occurs when a Migration status is changed.
Status changes during the migrartion creation process are ignored and will not produce webhook events.
{
"data": [
{
"id": "3322",
"type": "migration.statusChanged",
"attributes": {
"createdAt": "2024-05-23T07:11:41.392Z",
"previousStatus": "MigratingAccounts",
"status": "CollectingMoneyMovementConsent"
},
"relationships": {
"migration": {
"data": {
"id": "10047",
"type": "customerBankMigration"
}
},
"customer": {
"data": {
"id": "10064",
"type": "customer"
}
}
}
}
]
}
account.migrated
Occurs when an Account is migrated successfully.
{
"data": [
{
"id": "3727",
"type": "account.migrated",
"attributes": {
"createdAt": "2024-05-19T11:17:54.678Z",
"toBank": "XYZ bank"
},
"relationships": {
"account": {
"data": {
"id": "10020",
"type": "account"
}
},
"newAccount": {
"data": {
"id": "11257",
"type": "account"
}
},
"customer": {
"data": {
"id": "10003",
"type": "customer"
}
}
}
}
]
}