Sending and Receiving Funds
Learn how to send or receive funds
Transfer is only supported in Plaid's Sandbox and Production environments.
Prerequisites
Integrate Plaid’s front-end library, Plaid Link, to authenticate user bank accounts and create Items.
Create a Link token using
/link/token/create
with the parameterproducts
set to['transfer']
, then initialize Link with this token. Ensure that you initialize Link with only thetransfer
product. Ensure also that you have an access token and associated Items in a good state.If an Item is not in a good state (i.e., you receive
decision: "approved"
anddecision_rationale.code: "USER_LOGIN_REQUIRED"
when calling/transfer/authorization/create
), use Link in Update Mode to re-authenticate your user and retry the authorization. You can still create a transfer in this state, but it's best practice and in your best interest to only process transfers when an Item is in a good state (i.e., you receivedecision: "approved"
anddecision_rationale: null
when calling/transfer/authorization/create
) to minimize the risk of an ACH return.The
access_token
must be associated with a depository checking or savings account.
Determine the transfer failure risk
To determine the transfer failure risk, call the /transfer/authorization/create
endpoint with the following:
The user's
access_token
and theaccount_id
that represents the account where you'd like to send funds toThe
amount
(fund amount) you’re sendingtype
ascredit
if sending funds, ortype
asdebit
if receiving fundsach_class
asppd
for an personal account, or asccd
for a business accountuser
object withlegal_name
and other information (if you've specifiedccd
as theach_class
, you'll also need to specify the business’s name on the account within theuser.legal_name
parameter; if set to a person’s name it will be rejected).
1const request: TransferAuthorizationCreateRequest = {2 access_token: 'ACCESS_TOKEN',3 account_id: '3gE5gnRzNyfXpBK5wEEKcymJ5albGVUqg77gr',4 type: 'credit',5 network: 'ach',6 amount: '12.34',7 ach_class: 'ppd',8 user: {9 legal_name: 'Anna Charleston',10 },11};1213try {14 const response = await client.transferAuthorizationCreate(request);15 const authorizationId = response.data.authorization.id;16} catch (error) {17 // handle error18}
The response will contain an authorization
object with details about the transfer authorization, including:
authorization.id
, you'll need this to create the transfer in next step (this expires after 24 hours so you should persist this in a datastore)authorization.decision
, the decision from the authorization engine regarding the transfer. If this decision is"approved"
, you can proceed to the next step and create the transfer. If thedecision
is"declined"
, you will not be able to create the transfer (for more information on thedecision
anddecision_rationale
fields, see Transfer decision authorization).
1{2 "authorization": {3 "id": "460cbe92-2dcc-8eae-5ad6-b37d0ec90fd9",4 "created": "2020-08-06T17:27:15Z",5 "decision": "approved",6 "decision_rationale": null,7 "proposed_transfer": {8 "ach_class": "ppd",9 "account_id": "3gE5gnRzNyfXpBK5wEEKcymJ5albGVUqg77gr",10 "type": "credit",11 "user": {12 "legal_name": "Anna Charleston",13 "phone_number": "510-555-0128",14 "email_address": "acharleston@email.com",15 "address": {16 "street": "100 Market Street",17 "city": "San Francisco",18 "region": "California",19 "postal_code": "94103",20 "country": "US"21 }22 },23 "amount": "12.34",24 "network": "ach",25 "origination_account_id": "0123-4567-8901-2345-67890123"26 }27 },28 "request_id": "saKrIBuEB9qJZno"29}
Create the transfer
Create the transfer by calling the /transfer/create
endpoint with the following:
The
authorization_id
of the transfer (returned from the previous step)The unique
authorization_id
you must generate (for more information, see Transfer authorization id)user’s
access_token
andaccount_id
you want funds to be sent toamount
you’re sendingtype
ascredit
(i.e., a push payment)network (either
same-day-ach
orach
)ach_class
(eitherppd
for an personal account orccd
for a business account)user
object withlegal_name
and other information (if you've specifiedccd
as theach_class
, you'll also need to specify the business’s name on the account within theuser.legal_name
parameter; if set to a person’s name it will be rejected).
Many of these parameters are the same as those specified when determining the transfer failure risk. This is in case you'd like to process an amount different from the amount that was authorized (only for amounts less than the original). For example, you may initially authorize for $100, but may only need to charge the user $90.
1const request: TransferCreateRequest = {2 type: 'credit',3 network: 'ach',4 amount: '12.34',5 description: 'payment',6 ach_class: 'ppd',7 user: {8 legal_name: 'Anna Charleston',9 },10 access_token: accessToken,11 account_id: '3gE5gnRzNyfXpBK5wEEKcymJ5albGVUqg77gr',12 authorization_id: '231h012308h3101z21909sw',13};14try {15 const response = await client.transferCreate(request);16 const transfer = response.data.transfer;17} catch (error) {18 // handle error19}
In the response is a transfer
object. We recommend persisting the transfer.id
in a datastore as you’ll need this when reconciling transactions or canceling a transaction.
1{2 "transfer": {3 "id": "460cbe92-2dcc-8eae-5ad6-b37d0ec90fd9",4 "ach_class": "ppd",5 "account_id": "3gE5gnRzNyfXpBK5wEEKcymJ5albGVUqg77gr",6 "type": "credit",7 "user": {8 "legal_name": "Anna Charleston",9 "phone_number": "510-555-0128",10 "email_address": "acharleston@email.com",11 "address": {12 "street": "100 Market Street",13 "city": "San Francisco",14 "region": "California",15 "postal_code": "94103",16 "country": "US"17 }18 },19 "amount": "12.34",20 "description": "A description of the transfer",21 "created": "2020-08-06T17:27:15Z",22 "status": "pending",23 "network": "ach",24 "cancellable": true,25 "failure_reason": null,26 "metadata": {27 "key1": "value1",28 "key2": "value2"29 },30 "origination_account_id": "0123-4567-8901-2345-67890123"31 },32 "request_id": "saKrIBuEB9qJZno"33}
Sample app code
For a real-life example of an app that incorporates the /transfer/authorization/create
and /transfer/create
endpoints, see the Node-based Plaid Pattern Transfer sample app. Pattern Transfer is a sample subscriptions payment app that enables ACH bank transfers. The Transfer create code can be found in transfers.js