Transfer wallet-to-wallet

Wallet-to-wallet transfers provide flexibility for accessing funds. Some examples of when wallet-to-wallet transfers are useful:

  • A goods or services based platform looking to allow immediate peer-to-peer payments
  • A company wants to make payouts and give their workers the option to choose their method of disbursement
  • A subscription based company has been accumulating payments over a period of time (day, week, etc.) before sending payouts to their employees’ wallets.

Below, we provide instructions on how to implement wallet-to-wallet transfers with Moov.

1. Get started

Before you begin setting up a wallet-to-wallet transfer, you’ll need to:

For more detailed instructions on how to get your API keys and access token, read our Quick start guide.

2. Set up the source account

You will start by creating a Moov account for the entity that’s sending money (what we’ll call the source account) and requesting the send-funds and wallet capabilities.

The capabilities endpoint will specify what information Moov needs about the source account holder before we enable the requested capability.

In the following example, the source account is a local gym business called “Whole Body Fitness”.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
curl -X POST "https://api.moov.io/accounts" \
  -H "Authorization: Bearer {token}" \
  --data-raw '{
    "accountType": "business",
    "profile": {
      "business": {
        "legalBusinessName": "Whole Body Fitness LLC",
        "businessType": "llc"
      }
    },
    "capabilities": [
      "send-funds", 
      "wallet"
    ],
    "foreignId": "your-correlation-id"
  }'\
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
mc, _ := moov.NewClient()

mc.CreateAccount(ctx, moov.CreateAccount{
  Type: moov.AccountType_Business,
  Profile: moov.CreateProfile{
    Business: &moov.CreateBusinessProfile{
      Name: "Whole Body Fitness LLC",
      Type: moov.BusinessType_Llc,
    },
  },
  RequestedCapabilities: []moov.CapabilityName{
    moov.CapabilityName_SendFunds,
    moov.CapabilityName_Wallet,
  },
  ForeignID: "your-correlation-id",
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
const moov = new Moov(credentialsObject);

const accountPayload = {
  accountType: "business",
  profile: {
    business: {
      legalBusinessName: "Whole Body Fitness LLC",
      businessType: "llc"
    }
  },
  capabilities: [
    "send-funds", 
    "wallet"
  ],
  foreignId: "your-correlation-id"
};

const account = await moov.accounts.create(accountPayload);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
const moov = Moov(token);

const accountPayload = {
  accountType: "business",
  profile: {
    business: {
      legalBusinessName: "Whole Body Fitness LLC",
      businessType: "llc"
    }
  },
  capabilities: [
    "send-funds", 
    "wallet"
  ],
  foreignId: "your-correlation-id"
};

const account = await moov.accounts.create({accountPayload});
The send-funds and wallet capabilities share the same requirements, so the wallet capability should be enabled instantly if you already have send-funds enabled.

3. Set up the destination account

Next, you’ll create a Moov account for the entity receiving funds (otherwise known as the destination account) and request, at minimum, the transfer and wallet capabilities. Once again, the capabilities endpoint will specify what information we’ll need about the destination account holder before the capabilities are enabled.

In the example provided, we are creating an account for a fitness instructor, “Jules Jackson”, who works at the Whole Body Fitness gym.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
curl -X POST "https://api.moov.io/accounts" \
  -H "Authorization: Bearer {token}" \
  -H "X-Wait-For: connection" \
  --data-raw '{
  "accountType": "individual",
  "profile": {
    "individual": {
      "address": {
        "addressLine1": "123 Main Street",
        "addressLine2": "Apt 302",
        "city": "Boulder",
        "stateOrProvince": "CO",
        "postalCode": "80301",
        "country": "US"
      },
      "birthDate": {
        "day": "09",
        "month": "05",
        "year": "1985"
      },
      "email": "julesjacksonyoga@moov.io",
      "governmentID": {
        "ssn": {
          "full": "111111111",
          "lastFour": "1111"
        }
      },
      "name": {
        "firstName": "Jules",
        "lastName": "Jackson"
      },
      "phone": {
        "number": "8185551212",
        "countryCode": "1"
      },
    }
  },
  "capabilities": [
    "transfers", 
    "send-funds", 
    "wallet"
  ],
  "foreignId": "your-correlation-id",
  "metadata": {
    "property1": "string",
    "property2": "string"
  },
  "mode": "production",
  "settings": {
    "cardPayment": {
      "statementDescriptor": "Jules Jackson"
    }
  },
  "termsOfService": {
    "token": "kgT1uxoMAk7QKuyJcmQE8nqW_HjpyuXBabiXPi6T83fUQoxsyWYPcYzuHQTqrt7YRp4gCwyDQvb6U5REM9Pgl2EloCe35t-eiMAbUWGo3Kerxme6aqNcKrP_6-v0MTXViOEJ96IBxPFTvMV7EROI2dq3u4e-x4BbGSCedAX-ViAQND6hcreCDXwrO6sHuzh5Xi2IzSqZHxaovnWEboaxuZKRJkA3dsFID6fzitMpm2qrOh4"
  },
}'\
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const moov = new Moov(credentialsObject);

const accountPayload = {
  accountType: "individual",
  profile: {
    individual: {
      address: {
        addressLine1: "123 Main Street",
        addressLine2: "Apt 302",
        city: "Boulder",
        stateOrProvince: "CO",
        postalCode: "80301",
        country: "US"
      },
      birthDate: {
        day: "09",
        month: "05",
        year: "1985"
      },
      email: "julesjacksonyoga@moov.io",
      governmentID: {
        ssn: {
          full: "111111111",
          lastFour: "1111"
        }
      },
      name: {
        firstName: "Jules",
        lastName: "Jackson"
      },
      phone: {
        number: "8185551212",
        countryCode: "1"
      },
    }
  },
  capabilities: [
    "transfers", 
    "send-funds", 
    "wallet"
  ],
  foreignId: "your-correlation-id",
  metadata: {
    property1: "string",
    property2: "string"
  },
  mode: "production",
  settings: {
    cardPayment: {
      statementDescriptor: "Jules Jackson"
    }
  },
  termsOfService: {
    token: "kgT1uxoMAk7QKuyJcmQE8nqW_HjpyuXBabiXPi6T83fUQoxsyWYPcYzuHQTqrt7YRp4gCwyDQvb6U5REM9Pgl2EloCe35t-eiMAbUWGo3Kerxme6aqNcKrP_6-v0MTXViOEJ96IBxPFTvMV7EROI2dq3u4e-x4BbGSCedAX-ViAQND6hcreCDXwrO6sHuzh5Xi2IzSqZHxaovnWEboaxuZKRJkA3dsFID6fzitMpm2qrOh4"
  },
};

const account = await moov.accounts.create(accountPayload);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const moov = Moov(token);

const accountPayload = {
  accountType: "individual",
  profile: {
    individual: {
      address: {
        addressLine1: "123 Main Street",
        addressLine2: "Apt 302",
        city: "Boulder",
        stateOrProvince: "CO",
        postalCode: "80301",
        country: "US"
      },
      birthDate: {
        day: "09",
        month: "05",
        year: "1985"
      },
      email: "julesjacksonyoga@moov.io",
      governmentID: {
        ssn: {
          full: "111111111",
          lastFour: "1111"
        }
      },
      name: {
        firstName: "Jules",
        lastName: "Jackson"
      },
      phone: {
        number: "8185551212",
        countryCode: "1"
      },
    }
  },
  capabilities: [
    "transfers", 
    "send-funds", 
    "wallet"
  ],
  foreignId: "your-correlation-id",
  metadata: {
    property1: "string",
    property2: "string"
  },
  mode: "production",
  settings: {
    cardPayment: {
      statementDescriptor: "Jules Jackson"
    }
  },
  termsOfService: {
    token: "kgT1uxoMAk7QKuyJcmQE8nqW_HjpyuXBabiXPi6T83fUQoxsyWYPcYzuHQTqrt7YRp4gCwyDQvb6U5REM9Pgl2EloCe35t-eiMAbUWGo3Kerxme6aqNcKrP_6-v0MTXViOEJ96IBxPFTvMV7EROI2dq3u4e-x4BbGSCedAX-ViAQND6hcreCDXwrO6sHuzh5Xi2IzSqZHxaovnWEboaxuZKRJkA3dsFID6fzitMpm2qrOh4"
  },
};

const account = await moov.accounts.create({accountPayload});

4. Initiate the payment

Now that both the source and destination have been set up with their wallets and the ability to send and receive funds, you’re ready to create the payment.

Get a list of the available payment methods for both accounts

Use the transfer options endpoints to get a list of available payment methods for both accounts.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
curl -X POST "https://api.moov.io/transfer-options" \
  -H "Authorization: Bearer {token}" \
  --data-raw '{
    "amount": {
      "value": 100,
      "currency": "USD"
    }
    "destination": {
      "accountID": "UUID"
    },
    "source": {
      "accountID": "UUID"
    }
  }'\
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
const moov = new Moov(credentialsObject);

const transferOptions = {
  amount: {
    value: 100, 
    currency: "USD"
  },
  destination: {
    accountID: UUID
  },
  source: {
    accountID: UUID
  }
}

const options = await moov.transfers.getTransferOptions(transferOptions);

The response will include all the payment methods the source and destination can use based on their linked bank accounts, capabilities, and the amount of the transfer. Select the moov-wallet payment method.

Set up the transfer between the source and destination

Create a transfer between the two accounts, using the payment method IDs you got earlier in the transfer options request. Note that you cannot use Moov.js to make a transfer.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
curl -X POST "https://api.moov.io/transfers" \
  -H "Authorization: Bearer {token}" \
  -H "X-Idempotency-Key: UUID" \
  -H "X-Wait-For: rail-response" \
  --data-raw '{
    "amount": {
      "value": 100,
      "currency": "USD"
    },
    "destination": {
      "paymentMethodID": "UUID"
    },
    "source": {
      "paymentMethodID": "UUID"
    },
    "description": "Optional transaction description."
  }'\
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
mc, _ := moov.NewClient()

mc.CreateTransfer(ctx, moov.CreateTransfer{
  Amount: moov.Amount{
    Currency: "usd",
    Value:    100, // $1.00
  },
  Destination: moov.CreateTransfer_Destination{
    PaymentMethodID: "UUID",
  },
  Source: moov.CreateTransfer_Source{
    PaymentMethodID: "UUID",
  },
  Description: "Optional transaction description.",
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
const moov = new Moov(credentialsObject);

const transfer = await moov.transfers.create({
  amount: {
    value: 100,
    currency: "USD"
  },
  destination: {
    paymentMethodID: "UUID"
  },
  source: {
    paymentMethodID: "UUID"
  },
  description: "Optional transaction description."
});

What’s next

Feel free to explore our API reference or take a look at our additional step by step guides:

Summary Beta