Transfers
Transfers APIs can be used to enable customers to move funds to and from internal accounts, purses, and external bank accounts.
Overview
The transfers API allows partners to enable their customers to move funds to and from internal accounts, purses, and external bank accounts.
Transfer Idempotency
If a POST Transfers call is attempted, a subsequent time, with the same RequestID or transferIdentifier:
The API will return a response indicating the current status of the initial POST Transfer call.
An idempotent POST Transfers call will not automatically cause a pending transfer to re-execute. Instead, any pending transfers will be automatically retried by a background process.
A failed or declined transfer is not retriable.
If a prior request was not received, then a subsequent idempotent request will be treated like an initial request.
Please note that although transferIdentifier is optional, if it is used, it must be unique between each Transfer.
Transfers During Holidays
Since banks are closed on federal holidays, we advise all partners not to set up ACH transfers on those days. When you do, the transaction will result in a rejected status. To re-submit the same ACH transfer on another day, you must be sure to provide a new, unique Transferidentifier to avoid a subsequent reject.
Transfers API Endpoints
Assess Transfers Prerequisites
This endpoint allows Partners to assess if the required pre-requisites are met before one of the above transfer types is processed. It also verifies that the user has gone through identity verification with Green Dot.
Assessment includes the following transfer types:
peerPayment (p2p): Funds transfer to and from customer accounts under the same Partner account
achOut: Funds transfer to an external bank account
IFT Out: Instant funds transfer to an external card
IFT Send: Instant funds transfer from an external card to a customer’s account
IFT Load: Instant funds transfer from a customer’s external bank card to a Green Dot account
API Call Structure
POST /programs/{programCode}/transfers/assessment
Sample Request - P2P
{
"transferIdentifier":"8c6d1bc8-edc8-43a5-b2fa-193b451c9a49",
"transferType":"peerPayment",
"transferAuthorizationType":"execute",
"initiator":"8eef5828-51a7-46b1-b954-ff80fecb6432",
"transferRoute":{
"transactionAmount":1.00,
"sourceTransferEndpoint":{
"transferEndpointType":"account",
"identifier":"dc79b774-eab5-4025-a87c-0e4cafaa664f",
"handleData":{
"handle":"",
"firstName":"John",
"lastName":"Doe",
"userName":"johndoe123"
},
"currency":"USD"
},
"targetTransferEndpoint":{
"transferEndpointType":"account",
"identifier":"bd64e362-2bc3-439a-b410-a088a083e35f",
"handleData":{
"handle":"6505760505",
"firstName":"Jane",
"lastName":"Smith",
"userName":"JaneSmith987"
},
"currency":"USD"
}
},
"fraudData":{
"key":"string",
"key":{
"prop1":"test",
"prop2":"BaaS"
}
}
}
Sample Response - P2P
{
"limits":[
{
"type":"balanceLimit",
"frequency":"notApplicable",
"minimumAmount":0.0,
"maximumAmount":50000.0
},
{
"type":"peerTransferSendPerUseLimit",
"frequency":"perUse",
"minimumAmount":1.0,
"maximumAmount":1000.0
},
{
"type":"peerTransferSendVelocityLimit",
"frequency":"weekly",
"minimumAmount":0.0,
"maximumAmount":3000.0,
"amountRemaining":2800.0
},
{
"type":"peerTransferReceiveVelocityLimit",
"frequency":"weekly",
"minimumAmount":0.0,
"maximumAmount":3000.0,
"amountRemaining":2800.0
}
],
"responseDetails":[
{
"code":0,
"subCode":0,
"description":"Success",
"url":"http://tbd"
}
]
}
Transfer Funds
This endpoint accommodates transferring funds for the following transfer types:
- peerPayment (p2p) -- Funds transfer to and from accounts under the same Partner account
- achOut -- Funds transfer to an external bank account
- achPull -- Funds transfer from an external bank account
- disbursementIn -- Funds transfer from a program funding source to a consumer account
- disbursementOut -- Funds transfer from a consumer account to a program funding source
- IFT Out -- Instant funds transfer to an external card
- IFT Send -- Instant funds transfer from an external card to a customer’s account
- IFT Load -- Instant funds transfer from a customer’s external bank card to a Green Dot account
API Call Structure
POST /programs/{programCode}/transfers
Sample Request Body - IFT Send
{
"transferIdentifier":"E6204956-54AD-49ED-BE85-31A52A647C1E",
"transferType":"iftSend",
"transferAuthorizationType":"system",
"initiator":"7936b6f9-38a9-455a-ad19-6a26cce46c90",
"memo":"this is a test",
"partnerReferenceData":"",
"transferRoute":{
"transactionAmount":1,
"sourceTransferEndpoint":{
"transferEndPointType":"card",
"identifier":"17D94213-E41E-46B1-AD61-97A20CFCAE32",
"currency":"USD",
"encryptedCardData":{
"version":"EC_v1",
"ephemeralPublicKey":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUyPhRsvq8PFmQtm+7YVPv7KjHp8+/4zhXjT77bSdbW6Z94LNsmRTTEPAPh5SZseVwSpXqQRbPcqZyxGbypOnXg==",
"publicKeyHash":"PiRV5ko8JYGxAtcNb9WV4aVg7aXIp8EsstmeUqqWzT8=",
"data":"A1DRYX+btumVbPqcUeGPm4dVF0G5e6sozVWcRMOgOXHplAYKb4uq7NmnYBuxVMG8ZkvnLftET4QRLlbNNGfsrwPtiZQware03uOFzlaZj8NXOZrqVJve9k5eHtD1blWvaMAk+OnamuaOFmuqUlakAQv07i9d75vAYZde1rnkIAOm8Hl1l7y/lVVpdRICFpFkXYxcsdLoHOt2XjRueK1HhurXD2lXdH1DMx8dTa4M/2Kc6wO14O7BV1Xv8W5iIEkHLgoujnpkjdBS52RgxAR/xaQqXe9KijyUcMGyDCC1kWAWehE+UHFdKLQuvoNhgKYNMJjvYWDN8ZHkkaookx5/YaIztPX4DPw9"
}
},
"targetTransferEndpoint":{
"transferEndPointType":"account",
"identifier":"384d43b4-d046-4c3d-8453-584a0e8d6b1c",
"currency":"USD",
"handleData":{
"handle":"",
"firstName":"lucy",
"lastName":"li",
"userName":"lucy li"
}
}
},
"fraudData":{
"ForterMobileUID":"abc",
"CustomerIP":"255.255.240.0"
}
}
Transferring Funds To and From Purses
This endpoint accommodates transferring funds between balances (purses) within the same customer account. These balances are referred to as purses and can be given a purse description by the customer. Example: savings goal - car
Note: The system will check across all purses for the account max balance.
API Call Structure
POST /programs/{programCode}/transfers
Purse to Purse Transfer Retry
Partially completed purse to purse transfers will be automatically completed or reversed, so that the customer’s account balance is corrected.
How it Works
If the failed transaction is retryable, then the backend will attempt to complete the transfer repeatedly for up to 24 hours.
Then a final reversal attempt will be made. When this issue occurs and it is not corrected within 5 minutes, Green Dot Support should be contacted, and the issue investigated.
If the failed transaction is not retryable, then the backend will immediately reverse the transfer.
Account Status
When placing an account into Spend Down, the system will automatically transfer funds to the Primary purse. A Transaction Webhook will be generated for each non-spend purse that had its balance transferred.
Customers will be allowed to access their funds if their account is in a restricted, but curable state.
In these situations, a purse to purse transfer can be initiated and processed.
Note: If an account is restricted and incurable, the funds are automatically transferred to the primary purse by the system. Purse to purse transfers will not be allowed under these circumstances.
Business Rules
If the account is in spendDown or customerIntiatedSpendDown, then purse to purse transfers will not be allowed.
If the account is in a restricted, potential fraud state then purse to purse transfers will be allowed.
If the account is locked, purse to purse transfers will not be allowed.
Funds in a non-spend purse (savings) will be automatically moved to the available balance (primary purse) when an account is placed into a locked state with no cure (kycPendingGate = none).
Response Codes
Scenario | Code | subCode | Description |
---|---|---|---|
A purse to purse transfer is initiated and the customer’s account is in a restricted, spendDown, or customerInitiatedSpendDown status. | 3 | 100 | Funds cannot be transferred into a non-spend purse if an Account is in spend down. |
Once a savings purse has been successfully closed using the Close an Empty Balance Non-Spending Purse API, the system will not allow transfers into the closed savings purse. So, requests to transfer funds into a closed savings purse will fail. | 3 | 354 | Funds cannot be transferred to a closed purse. |
Terms Acceptance Enforcement
Depending on the terms and conditions included in the daa that is accepted during account registration, some features may need to be explicitly accepted via the PUT /accounts endpoint.
Initially, all programs will be configured to not enforce terms acceptance.
Once the system is configured to enforce terms acceptance for a feature, any customer that does not accept the terms for that feature will not be allowed to use the feature.
For any programs, where customers are already using features that may require explicit terms acceptance, a data backfill will be required for those customers prior to enforcement being enabled.
Please work with your Green Dot Account Manager and/or Product Manager to understand the impact and transition plan for your program and features.
Sample Request Body
{
"transferIdentifier":“0b830092-e5d4-45b8-ad26-8a42c94ddd4b”,
"transferType":"purse",
"transferAuthorizationType":"execute",
"initiator":“0b830092-e5d4-45b8-ad26-8a42c94ddd4c”,
"transferRoute":{
"transactionAmount":5.00,
"sourceTransferEndpoint":{
"transferEndpointType":"purse",
"identifier":“0b830092-e5d4-45b8-ad26-8a42c94ddd4d”
},
"targetTransferEndpoint":{
"transferEndpointType":"purse",
"identifier":“0b830092-e5d4-45b8-ad26-8a42c94ddd4f”
}
},
"fraudData":{
}
}
Request Parameters
Field | Description |
---|---|
transferIdentifier | If the transaction is initiated through the transfers API, then the transferIdentifier uniquely identifying the initiating transfer will be included. |
transferType | Type of transfer being done. Note: If the transferType is purse, a minimum transfer limit and a maximum transfer limit can be optionally applied and enforced. By default, limits will be from 0.01 to the maximum account balance for the purse transferType. Contact your product liaison at Green Dot to determine if any of these limits have been or should be configured for your programCode. |
transferAuthorizationType | |
initiator | Source of transfer |
transferRoute | Contains information about the source and target of each new transfer. |
transactionAmount | Amount of transaction excluding fees. |
sourceTransferEndpoint | Contains information about the source of the transfer. |
transferEndpointType | Type of endpoint the transfer is coming from, i.e. purse |
Identifier | Unique identifier of the purse that the transfer is coming from. |
targetTransferEndpoint | Contains the encrypted data of the endpoint (purse) that the transfer is going to. |
transferEndpointType | Type of endpoint the transfer is going to, i.e. purse. |
Identifier | Unique identifier of the purse that the transfer is going to. |
fraudData | Value used to exchange fraud related information about the user or account. Structure is defined per product. |
Sample Response Body
{
"responseDetails":[
{
"code":0,
"subCode":0,
"description":"string",
"url":"string"
}
],
"transfer":{
"transferIdentifier":“5b830092-e5d4-45b8-ad26-8a42c94aaa5e”,
"transferStatus":"completed"
},
"accounts":[
{
"accountIdentifier":“0b830092-e5d4-45b8-ad26-8a42c94ddd4c”,
"purses":[
{
"purseIdentifier":“562a27ec-6cae-4459-a522-be94b4570f78”,
"purseType":"primary",
"availableBalance":10.55,
"ledgerBalance":10.55,
"availableBalanceAsOfDateTime":"“2019-01-10T21":"56":00.310Z”,
"ledgerBalanceAsOfDateTime":"“2019-01-10T21":"56":00.310Z”
},
{
"purseIdentifier":“e02becde-9cab-4aea-90d1-14a1bcccfb58”,
"purseType":"savings",
"purseDescription":"savings goal – car",
"availableBalance":20.11,
"ledgerBalance":20.11,
"availableBalanceAsOfDateTime":"“2019-01-10T21":"56":00.310Z”,
"ledgerBalanceAsOfDateTime":"“2019-01-10T21":"56":00.310Z”
}
]
}
],
"fraudData":{
}
}
Sample Response Parameters
Field | Description |
---|---|
responseDetails,code subCode,description,url | See Response Details |
transfer | Contains the identifier and status of the transfer. |
transferIdentifier | A unique identifier for each transfer. Note: It is recommended that the partner provide their own transfer identifiers. If not provided, then the requestId is used as the transferIdentifier. |
transferStatus | Status of transfer (i.e. completed, pending, failed, or canceled) |
accounts | Contains detailed information about the account. |
accountIdentifier | Unique identifier of an account within a program. |
Purses | Returns purse associated with account. Note: A purse is a balance holding object. |
purseIdentifier | Unique identifier for a purse. |
purseType | Type of purse |
availableBalance | Number value representing the amount of funds available for use. Pending transactions are included. |
ledgerBalance | Number value that represents the balance of the account based on all activities that have been posted to the associated ledger. |
availableBalanceAsOfDateTime | The date and time (UTC) that the available balance is reflective of. Note: Since events can be published out of chronological order, do not update the available balance if a more recent available balance as of date was previously processed. |
ledgerBalanceAsOfDateTime | The date and time (UTC) that the ledger balance is reflective of. Note: Since events can be published out of chronological order, do not update the ledger balance if a more recent ledger balance as of date was previously processed. |
purseIdentifier | Unique identifier for a purse. |
purseType | Type of purse |
purseDescription | Description of purse |
availableBalance | Number value representing the amount of funds available for use. |
ledgerBalance | Number value that represents the balance of the account based on all activities that have been posted to the associated ledger. |
availableBalanceAsOfDateTime | The date and time (UTC) that the available balance is reflective of. Note: Since events can be published out of chronological order, do not update the available balance if a more recent available balance as of date was previously processed. |
ledgerBalanceAsOfDateTime | The date and time (UTC) that the ledger balance is reflective of. Note: Since events can be published out of chronological order, do not update the ledger balance if a more recent ledger balance as of date was previously processed. |
fraudData | Value used to exchange fraud related information about the user or account. Structure is defined per product. |
Update Existing Transfer
This API updates details for an existing transfer transaction.
API Call Structure
PUT /programs/{programCode}/transfers/{transferIdentifier}
Request Body
{
"transferAuthorizationType": "string",
"transferEndpoint": {
"isSource": true,
"transferEndPointType": "string",
"identifier": "string",
"encryptedCardData": {
"version": "string",
"ephemeralPublicKey": "string",
"publicKeyHash": "string",
"data": "string"
}
},
"debitToNegative": true,
"device": {
"deviceId": "string",
"deviceMake": "string",
"deviceVersion": "string",
"deviceOS": "string",
"deviceOSVersion": "string",
"ipAddress": "string",
"customerIP": "string"
}
}
Response Body
{
"transfer": {
"transferStatus": "string"
},
"responseDetails": [
{
"code": 0,
"subCode": 0,
"description": "string",
"url": "string"
}
]
}
Update Existing Transfer (Guest Checkout)
This API updates details for an existing transfer transaction.
API Call Structure
POST /programs/{programCode}/transfers/{transferToken}/guestcheckout
Request Body
{
"device": {
"deviceId": "string",
"deviceMake": "string",
"deviceVersion": "string",
"deviceOS": "string",
"deviceOSVersion": "string",
"ipAddress": "string",
"customerIP": "string"
}
}
Response Body
{
"transferIdentifier": "string",
"transferStatus": "string",
"transferType": "string",
"transferStatusReason": "string",
"transactionAmount": 0,
"memo": "string",
"targetInformation": {
"accountIdentifier": "string",
"purseIdentifier": "string",
"purseNumber": "string",
"firstName": "string",
"lastName": "string",
"nickName": "string",
"handle": "string",
"merchantName": "string",
"storeNumber": "string",
"city": "string",
"state": "string",
"last4Pan": "string",
"association": "string",
"fundingSource": "string",
"accountNumber": "string",
"bankName": "string",
"status": "string",
"last4AccountNumber": "string"
},
"sourceInformation": {
"accountIdentifier": "string",
"purseIdentifier": "string",
"purseNumber": "string",
"firstName": "string",
"lastName": "string",
"nickName": "string",
"handle": "string",
"merchantName": "string",
"storeNumber": "string",
"city": "string",
"state": "string",
"last4Pan": "string",
"association": "string",
"fundingSource": "string",
"accountNumber": "string",
"bankName": "string",
"status": "string",
"last4AccountNumber": "string"
},
"fees": [
{
"identifier": "string",
"feeType": "string",
"description": "string",
"amount": 0,
"currency": "string",
"frequency": "string",
"localizedDisplayName": "string"
}
],
"velocityLimitStatus": "string",
"responseDetails": [
{
"code": 0,
"subCode": 0,
"description": "string",
"url": "string"
}
]
}
Create Transfer Token
This API creates a transfer token.
API Call Structure
POST /programs/{programCode}/account/{accountIdentifier}/token/create
Request Body
{
"AccountReferenceId": "string",
"deviceType": 0,
"options": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
}
Response Body
{
"responseCode": "string",
"linkToken": "string",
"errorCode": "string",
"errorMessage": "string",
"errorType": "string",
"responseDetails": [
{
"code": 0,
"subCode": 0,
"description": "string",
"url": "string"
}
]
}
Updated 10 months ago