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

ScenarioCodesubCodeDescription
A purse to purse transfer is initiated and the customer’s account is in a restricted, spendDown, or customerInitiatedSpendDown status.3100Funds 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.3354Funds 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

FieldDescription
transferIdentifierIf the transaction is initiated through the transfers API, then the transferIdentifier uniquely identifying the initiating transfer will be included.
transferTypeType 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
initiatorSource of transfer
transferRouteContains information about the source and target of each new transfer.
transactionAmountAmount of transaction excluding fees.
sourceTransferEndpointContains information about the source of the transfer.
transferEndpointTypeType of endpoint the transfer is coming from, i.e. purse
IdentifierUnique identifier of the purse that the transfer is coming from.
targetTransferEndpointContains the encrypted data of the endpoint (purse) that the transfer is going to.
transferEndpointTypeType of endpoint the transfer is going to, i.e. purse.
IdentifierUnique identifier of the purse that the transfer is going to.
fraudDataValue 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

FieldDescription
responseDetails,code subCode,description,urlSee Response Details
transferContains the identifier and status of the transfer.
transferIdentifierA 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.
transferStatusStatus of transfer (i.e. completed, pending, failed, or canceled)
accountsContains detailed information about the account.
accountIdentifierUnique identifier of an account within a program.
PursesReturns purse associated with account. Note: A purse is a balance holding object.
purseIdentifierUnique identifier for a purse.
purseTypeType of purse
availableBalanceNumber value representing the amount of funds available for use. Pending transactions are included.
ledgerBalanceNumber value that represents the balance of the account based on all activities that have been posted to the associated ledger.
availableBalanceAsOfDateTimeThe 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.
ledgerBalanceAsOfDateTimeThe 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.
purseIdentifierUnique identifier for a purse.
purseTypeType of purse
purseDescriptionDescription of purse
availableBalanceNumber value representing the amount of funds available for use.
ledgerBalanceNumber value that represents the balance of the account based on all activities that have been posted to the associated ledger.
availableBalanceAsOfDateTimeThe 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.
ledgerBalanceAsOfDateTimeThe 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.
fraudDataValue 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"
    } 
 ]
}