{"__v":1,"_id":"57e95dd45c01360e00a2c190","category":{"__v":7,"_id":"55fa37ca8065a10d004e5bb7","pages":["55fa37ca8065a10d004e5bbb","55fa37ca8065a10d004e5bbc","55fa37ca8065a10d004e5bbd","55fa37ca8065a10d004e5bbe","55fa37ca8065a10d004e5bbf","55fa37ca8065a10d004e5bc0","55fa3a948065a10d004e5bd5","55fa3c3ba663c00d00773dce","55fa4b8eaba81f0d00a115e4","56733ae758c4890d00bb548a","56734f9c4b2a680d00524e09","569d8eae3dbdc20d005feee8"],"project":"54e405191e51932d006abc39","version":"55fa37c88065a10d004e5bb6","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-02-18T03:20:58.779Z","from_sync":false,"order":0,"slug":"introduction","title":"Introduction"},"parentDoc":null,"project":"54e405191e51932d006abc39","user":"54e4044e8ef7552300409dcb","version":{"__v":7,"_id":"55fa37c88065a10d004e5bb6","project":"54e405191e51932d006abc39","createdAt":"2015-09-17T03:47:20.956Z","releaseDate":"2015-09-17T03:47:20.956Z","categories":["55fa37ca8065a10d004e5bb7","55fa37ca8065a10d004e5bb8","55fa37ca8065a10d004e5bb9","55fa37ca8065a10d004e5bba","55fca6bf34ae7c0d00ab8ea0","55ff80fd9e7ccf0d000a1d93","560220af7435de0d00fabd0d","56107f21bb9d920d00303e70","563e184077681a0d00d96a02","56fafc6596ec7e0e002ac85f"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"REST V3","version_clean":"3.1.0","version":"3.1"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-09-26T17:41:40.253Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"settings":"","results":{"codes":[]},"auth":"required","params":[],"url":""},"isReference":false,"order":8,"body":"One of the most common flows with Synapse is a payout flow. This is used by platforms that wish to send payments to individuals/businesses via their account. So something as follows:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/7702fc1-Untitled_Diagram_8.png\",\n        \"Untitled Diagram (8).png\",\n        343,\n        63,\n        \"#171717\"\n      ],\n      \"border\": false,\n      \"sizing\": \"smart\",\n      \"caption\": \"Platform X wants to send a payout to Bryan for payroll once every two weeks.\"\n    }\n  ]\n}\n[/block]\nIn this instance, the first thing the platform needs to do is [create](doc:create-a-user) a user account for Bryan in Synapse's system & make sure that the [platform has a `SYNAPSE-US` node created](https://help.synapsepay.com/hc/en-us/articles/216269798-Add-a-Bank-Account-on-the-Dashboard-Wire-Synapse-IOU-accounts).\n\n### Create account for Bryan:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"curl -X POST -H \\\"Content-Type: application/json\\\" -H \\\"X-SP-GATEWAY: e3f19e4bd4022c86e7f2|11c94ba6bad74d24a0158bc707f0fc19a86dc08f\\\" -H \\\"X-SP-USER-IP: 107.170.246.225\\\" -H \\\"X-SP-USER: |e716990e50b67a1177736960b6357524b22090ccab093d068b3d7a18dbde3f4c\\\" -d '{\\n  \\\"logins\\\": [\\n    {\\n      \\\"email\\\": \\\"bryan:::at:::test.com\\\"\\n    }\\n  ],\\n  \\\"phone_numbers\\\": [\\n    \\\"901.942.8167\\\"\\n  ],\\n  \\\"legal_names\\\": [\\n    \\\"Bryan Keltner\\\"\\n  ],\\n  \\\"extra\\\": {\\n    \\\"note\\\": \\\"Synapse account for Bryan Keltner\\\"\\n  }\\n}' \\\"https://sandbox.synapsepay.com/api/3/users\\\"\",\n      \"language\": \"curl\"\n    },\n    {\n      \"code\": \"{\\n  \\\"_id\\\": \\\"57e468f086c2733736c13314\\\",\\n  \\\"_links\\\": {\\n    \\\"self\\\": {\\n      \\\"href\\\": \\\"https://sandbox.synapsepay.com/api/3/users/57e468f086c2733736c13314\\\"\\n    }\\n  },\\n  \\\"client\\\": {\\n    \\\"id\\\": 844,\\n    \\\"name\\\": \\\"SynapsePay*Sandbox\\\"\\n  },\\n  \\\"doc_status\\\": {\\n    \\\"physical_doc\\\": \\\"MISSING|INVALID\\\",\\n    \\\"virtual_doc\\\": \\\"MISSING|INVALID\\\"\\n  },\\n  \\\"documents\\\": [],\\n  \\\"extra\\\": {\\n    \\\"cip_tag\\\": 1,\\n    \\\"date_joined\\\": 1474586864860,\\n    \\\"extra_security\\\": true,\\n    \\\"is_business\\\": false,\\n    \\\"supp_id\\\": \\\"\\\"\\n  },\\n  \\\"is_hidden\\\": false,\\n  \\\"legal_names\\\": [\\n    \\\"Bryan Keltner\\\"\\n  ],\\n  \\\"logins\\\": [\\n    {\\n      \\\"email\\\": \\\"bryan@test.com\\\",\\n      \\\"scope\\\": \\\"READ_AND_WRITE\\\"\\n    }\\n  ],\\n  \\\"permission\\\": \\\"UNVERIFIED\\\",\\n  \\\"phone_numbers\\\": [\\n    \\\"901.942.8167\\\"\\n  ],\\n  \\\"photos\\\": [],\\n  \\\"refresh_token\\\": \\\"refresh-3a09773f-388e-472b-ad1e-fccba7c2f152\\\"\\n}\",\n      \"language\": \"json\",\n      \"name\": \"Response\"\n    },\n    {\n      \"code\": \"const SynapsePay = require('synapsepay'); \\nconst Clients = SynapsePay.Clients;\\nconst Helpers = SynapsePay.Helpers;\\nconst Users = SynapsePay.Users;\\n\\nconst client = new Clients(\\n  'YOUR_CLIENT_ID',\\n  'YOUR_CLIENT_SECRET',\\n  IS_PRODUCTION # boolean\\n);\\n\\nconst userInfo = {\\n  logins: [\\n    {\\n      email: 'bryan@test.com'\\n    }\\n  ],\\n  phone_numbers: [\\n    '901.942.8167'\\n  ],\\n  legal_names: [\\n    'Bryan Keltner'\\n  ],\\n  extra: {\\n    note: 'Synapse account for Bryan Keltner'\\n  }\\n};\\n\\nlet bryan;\\n\\nUsers.create(\\n  client,\\n  // fingerprint (specific to user or static for application)\\n  process.env.FINGERPRINT,\\n  Helpers.getUserIP(),\\n  userInfo,\\n  function(err, userObj) {\\n    // store Bryan's info so we can access it in the future\\n    bryan = userObj; \\n  }\\n);\",\n      \"language\": \"javascript\",\n      \"name\": \"Node.js\"\n    }\n  ]\n}\n[/block]\nIn the response, you get back an `_id` associated with Bryan. You should store this `_id`, as this will be used in the future to access Bryan's account.\n\nYou should also notice that currently Bryan's account `permission` is `UNVERIFIED`. For Bryan to be able to receive funds, his permission at least needs to be `RECEIVE`. To be able to get there, we would need to add some KYC info to Bryan's account. Synapse is very versatile and can recognize over [3,000 unique KYC flows](https://medium.com/@sankaet/kyc-2-0-69d4d1acdc6d).\n\nFor the purpose of this tutorial, we will assume for Bryan to be able to get `RECEIVE` permissions, we need to supply Bryan's SSN number.\n\nTo submit this information, I first need to [OAuth](doc:get-oauth_key-refresh-token) Bryan & then [PATCH](doc:adding-documents) his account with the appropriate KYC information.\n\n\n### OAuth Bryan:\n\nIf you are using one of the Client libraries, this step is not required because the libraries automatically handle OAuth after the user is created.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"curl -X POST -H \\\"Content-Type: application/json\\\" -H \\\"X-SP-GATEWAY: e3f19e4bd4022c86e7f2|11c94ba6bad74d24a0158bc707f0fc19a86dc08f\\\" -H \\\"X-SP-USER-IP: 107.170.246.225\\\" -H \\\"X-SP-USER: |e716990e50b67a1177736960b6357524b22090ccab093d068b3d7a18dbde3f4c\\\" -d '{\\n    \\\"refresh_token\\\": \\\"refresh-3a09773f-388e-472b-ad1e-fccba7c2f152\\\"\\n}' \\\"https://sandbox.synapsepay.com/api/3/oauth/57e468f086c2733736c13314\\\"\",\n      \"language\": \"curl\"\n    },\n    {\n      \"code\": \"{\\n  \\\"expires_at\\\": \\\"1474594065\\\",\\n  \\\"expires_in\\\": \\\"7117\\\",\\n  \\\"oauth_key\\\": \\\"oauth-e8115f89-0153-4162-b024-36669ece4796\\\",\\n  \\\"refresh_expires_in\\\": 19,\\n  \\\"refresh_token\\\": \\\"refresh-3a09773f-388e-472b-ad1e-fccba7c2f152\\\"\\n}\",\n      \"language\": \"json\",\n      \"name\": \"Response\"\n    }\n  ]\n}\n[/block]\nFrom the response, we need to grab the `oauth_key` to make further requests on the user's behalf.\n\n### KYC Bryan:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"curl -X PATCH -H \\\"Content-Type: application/json\\\" -H \\\"X-SP-GATEWAY: e3f19e4bd4022c86e7f2|11c94ba6bad74d24a0158bc707f0fc19a86dc08f\\\" -H \\\"X-SP-USER-IP: 107.170.246.225\\\" -H \\\"X-SP-USER: oauth-e8115f89-0153-4162-b024-36669ece4796|e716990e50b67a1177736960b6357524b22090ccab093d068b3d7a18dbde3f4c\\\" -d '{\\n    \\\"documents\\\":[{\\n        \\\"email\\\":\\\"bryan@test.com\\\",\\n        \\\"phone_number\\\":\\\"901-942-8167\\\",\\n        \\\"ip\\\":\\\"101.110.226.221\\\",\\n        \\\"name\\\":\\\"Bryan Keltner\\\",\\n        \\\"alias\\\":\\\"Giggle\\\",\\n        \\\"entity_type\\\":\\\"M\\\",\\n        \\\"entity_scope\\\":\\\"Arts & Entertainment\\\",\\n        \\\"day\\\":2,\\n        \\\"month\\\":5,\\n        \\\"year\\\":1989,\\n        \\\"address_street\\\":\\\"4480 20th St\\\",\\n        \\\"address_city\\\":\\\"SF\\\",\\n        \\\"address_subdivision\\\":\\\"CA\\\",\\n        \\\"address_postal_code\\\":\\\"94114\\\",\\n        \\\"address_country_code\\\":\\\"US\\\",\\n        \\\"virtual_docs\\\":[{\\n            \\\"document_value\\\":\\\"111-1111-2222\\\",\\n            \\\"document_type\\\":\\\"SSN\\\"\\n        }]\\n    }]\\n}' \\\"https://sandbox.synapsepay.com/api/3/users/57e468f086c2733736c13314\\\"\",\n      \"language\": \"curl\"\n    },\n    {\n      \"code\": \"{\\n  \\\"_id\\\": \\\"57e468f086c2733736c13314\\\",\\n  \\\"_links\\\": {\\n    \\\"self\\\": {\\n      \\\"href\\\": \\\"https://sandbox.synapsepay.com/api/3/users/57e468f086c2733736c13314\\\"\\n    }\\n  },\\n  \\\"client\\\": {\\n    \\\"id\\\": 844,\\n    \\\"name\\\": \\\"SynapsePay*Sandbox\\\"\\n  },\\n  \\\"doc_status\\\": {\\n    \\\"physical_doc\\\": \\\"MISSING|INVALID\\\",\\n    \\\"virtual_doc\\\": \\\"SUBMITTED|VALID\\\"\\n  },\\n  \\\"documents\\\": [\\n    {\\n      \\\"id\\\": \\\"24fa1c3928a05354394bfa8bca6e876c05626bd540df41d8f870e6c3b544103f\\\",\\n      \\\"name\\\": \\\"Bryan Keltner\\\",\\n      \\\"permission_scope\\\": \\\"RECEIVE|1000|DAILY\\\",\\n      \\\"physical_docs\\\": [],\\n      \\\"social_docs\\\": [\\n        {\\n          \\\"document_type\\\": \\\"EMAIL\\\",\\n          \\\"id\\\": \\\"dd641c721c5c23ec66c3d27216dda6a85ce87b2f6717995c90b20eb69659f814\\\",\\n          \\\"last_updated\\\": 1474587319968,\\n          \\\"status\\\": \\\"SUBMITTED|VALID\\\"\\n        },\\n        {\\n          \\\"document_type\\\": \\\"PHONE_NUMBER\\\",\\n          \\\"id\\\": \\\"9dd593112385cfed22721355d279e79d33acd2c48cffe9c007b6c4acbfde826c\\\",\\n          \\\"last_updated\\\": 1474587320325,\\n          \\\"status\\\": \\\"SUBMITTED|VALID\\\"\\n        }\\n      ],\\n      \\\"virtual_docs\\\": [\\n        {\\n          \\\"document_type\\\": \\\"SSN\\\",\\n          \\\"id\\\": \\\"633c0873b9fc5acce12c2028b4324059d348bcfaffd661be7c405e5ed27a72a8\\\",\\n          \\\"last_updated\\\": 1474587320679,\\n          \\\"status\\\": \\\"SUBMITTED|VALID\\\"\\n        }\\n      ]\\n    }\\n  ],\\n  \\\"extra\\\": {\\n    \\\"cip_tag\\\": 1,\\n    \\\"date_joined\\\": 1474586864860,\\n    \\\"extra_security\\\": true,\\n    \\\"is_business\\\": false,\\n    \\\"supp_id\\\": \\\"\\\"\\n  },\\n  \\\"is_hidden\\\": false,\\n  \\\"legal_names\\\": [\\n    \\\"Bryan Keltner\\\"\\n  ],\\n  \\\"logins\\\": [\\n    {\\n      \\\"email\\\": \\\"bryan@test.com\\\",\\n      \\\"scope\\\": \\\"READ_AND_WRITE\\\"\\n    }\\n  ],\\n  \\\"permission\\\": \\\"RECEIVE\\\",\\n  \\\"phone_numbers\\\": [\\n    \\\"901.942.8167\\\"\\n  ],\\n  \\\"photos\\\": [],\\n  \\\"refresh_token\\\": \\\"refresh-3a09773f-388e-472b-ad1e-fccba7c2f152\\\"\\n}\",\n      \"language\": \"json\",\n      \"name\": \"Response\"\n    },\n    {\n      \"code\": \"const documents = {\\n  \\\"documents\\\":[{\\n    \\\"email\\\":\\\"bryan@test.com\\\",\\n    \\\"phone_number\\\":\\\"901-942-8167\\\",\\n    \\\"ip\\\":\\\"101.110.226.221\\\",\\n    \\\"name\\\":\\\"Bryan Keltner\\\",\\n    \\\"alias\\\":\\\"Giggle\\\",\\n    \\\"entity_type\\\":\\\"M\\\",\\n    \\\"entity_scope\\\":\\\"Arts & Entertainment\\\",\\n    \\\"day\\\":2,\\n    \\\"month\\\":5,\\n    \\\"year\\\":1989,\\n    \\\"address_street\\\":\\\"4480 20th St\\\",\\n    \\\"address_city\\\":\\\"SF\\\",\\n    \\\"address_subdivision\\\":\\\"CA\\\",\\n    \\\"address_postal_code\\\":\\\"94114\\\",\\n    \\\"address_country_code\\\":\\\"US\\\",\\n    \\\"virtual_docs\\\":[{\\n      \\\"document_value\\\":\\\"111-1111-2222\\\",\\n      \\\"document_type\\\":\\\"SSN\\\"\\n    }]\\n  }]\\n};\\n\\nbryan.addDocuments(\\n  documents,\\n  function(err, userObj) {\\n    // update Bryan's info to include documents\\n    bryan = userObj;\\n  }\\n);\",\n      \"language\": \"javascript\",\n      \"name\": \"Node.js\"\n    }\n  ]\n}\n[/block]\nAs you can see from the response now, Bryan has `RECEIVE` permissions. Also its worth noting that the `permission_scope` in his document is `RECEIVE|1000|DAILY`. Which means, Bryan can receive payments up to $1,000 daily. Again, all of this is customizable per platform. So you can always tweak your rules around daily or month limits or even what KYC needs to be submitted per user.\n\nNow Bryan's profile has been verified. We still however need to connect Bryan's bank account with his profile. To be able to do that, we will use [Nodes POST](doc:add-ach-us-node) API call. In this API call we can either use [account & routing number](doc:add-ach-us-node-via-acrt-s) to create an account or use [bank login credentials](doc:add-ach-us-node).\n\nIn case of Bryan, we will use the [account & routing number](doc:add-ach-us-node-via-acrt-s) method.\n\n### Link Bryan's bank account\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"curl -X POST -H \\\"Content-Type: application/json\\\" -H \\\"X-SP-GATEWAY: e3f19e4bd4022c86e7f2|11c94ba6bad74d24a0158bc707f0fc19a86dc08f\\\" -H \\\"X-SP-USER-IP: 107.170.246.225\\\" -H \\\"X-SP-USER: oauth-e8115f89-0153-4162-b024-36669ece4796|e716990e50b67a1177736960b6357524b22090ccab093d068b3d7a18dbde3f4c\\\"  -d '{\\n  \\\"type\\\": \\\"ACH-US\\\",\\n  \\\"info\\\": {\\n    \\\"nickname\\\": \\\"Fake Account\\\",\\n    \\\"account_num\\\": \\\"23456543234567543234567\\\",\\n    \\\"routing_num\\\": \\\"051000017\\\",\\n    \\\"type\\\": \\\"PERSONAL\\\",\\n    \\\"class\\\": \\\"CHECKING\\\"\\n  }\\n}' \\\"https://sandbox.synapsepay.com/api/3/users/57e468f086c2733736c13314/nodes\\\"\",\n      \"language\": \"curl\"\n    },\n    {\n      \"code\": \"{\\n  \\\"error_code\\\": \\\"0\\\",\\n  \\\"http_code\\\": \\\"200\\\",\\n  \\\"nodes\\\": [\\n    {\\n      \\\"_id\\\": \\\"57e46c6086c273634c2370f2\\\",\\n      \\\"_links\\\": {\\n        \\\"self\\\": {\\n          \\\"href\\\": \\\"https://sandbox.synapsepay.com/api/3/users/57e468f086c2733736c13314/nodes/57e46c6086c273634c2370f2\\\"\\n        }\\n      },\\n      \\\"allowed\\\": \\\"CREDIT\\\",\\n      \\\"extra\\\": {\\n        \\\"supp_id\\\": null\\n      },\\n      \\\"info\\\": {\\n        \\\"account_num\\\": \\\"4567\\\",\\n        \\\"bank_long_name\\\": \\\"BANK OF AMERICA, N.A.\\\",\\n        \\\"class\\\": \\\"CHECKING\\\",\\n        \\\"name_on_account\\\": \\\"Bryan Keltner\\\",\\n        \\\"nickname\\\": \\\"Fake Account\\\",\\n        \\\"routing_num\\\": \\\"0017\\\",\\n        \\\"type\\\": \\\"PERSONAL\\\"\\n      },\\n      \\\"is_active\\\": true,\\n      \\\"type\\\": \\\"ACH-US\\\"\\n    }\\n  ],\\n  \\\"success\\\": true\\n}\",\n      \"language\": \"json\",\n      \"name\": \"Response\"\n    },\n    {\n      \"code\": \"const Nodes = SynapsePay.Nodes;\\n\\nconst achPayload = {\\n  type: \\\"ACH-US\\\",\\n  info: {\\n    nickname: \\\"Fake Account\\\",\\n    account_num: \\\"23456543234567543234567\\\",\\n    routing_num: \\\"051000017\\\",\\n    type: \\\"PERSONAL\\\",\\n    class: \\\"CHECKING\\\"\\n  }\\n};\\n\\nlet bryansBank;\\n\\nNodes.create(\\n  bryan,\\n  achPayload,\\n  function(err, nodes) {\\n    bryansBank = nodes[0];\\n  }\\n);\",\n      \"language\": \"javascript\",\n      \"name\": \"Node.js\"\n    }\n  ]\n}\n[/block]\nThe response gives us the `_id` of the bank account we just linked with Bryan's account. Another thing worth noting here is the `allowed` property of the node. Currently its `CREDIT`. Since Bryan is only receiving funds, this status will do.\n\nThe next step is for us to create a transaction going from Platform X's `SYNAPSE-US` account to Bryan's `ACH-US` account.\n\n### Create Transaction\n\nSince the sender is Platform X, we need to get Platform X's `oauth_key` to be able to initiate this transaction. Either we can use the existing `oauth_key` or just [OAuth](doc:get-oauth_key-refresh-token) Platform X again.\n\nOnce we have the most recent `oauth_key`, we can create the transaction via [Transactions POST](doc:create-transaction) API call.\n\nWe will also need Bryan's `ACH-US` node `_id` for this, but that can be grabbed easily from the dashboard.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"curl -X POST -H \\\"Content-Type: application/json\\\" -H \\\"X-SP-GATEWAY: e3f19e4bd4022c86e7f2|11c94ba6bad74d24a0158bc707f0fc19a86dc08f\\\" -H \\\"X-SP-USER-IP: 107.170.246.225\\\" -H \\\"X-SP-USER: oauth-e8115f89-0153-4162-b024-36669ece4796|e716990e50b67a1177736960b6357524b22090ccab093d068b3d7a18dbde3f4c\\\" -H \\\"X-SP-IDEMPOTENCY-KEY: a938b7083253972554ce8e9dd5eb4e86e271b2a346d52ad136eccd21606d6299\\\" -d '{\\n    \\\"to\\\":{\\n      \\\"type\\\":\\\"ACH-US\\\",\\n      \\\"id\\\":\\\"57e46c6086c273634c2370f2\\\"\\n    },\\n    \\\"amount\\\":{\\n      \\\"amount\\\":1000,\\n      \\\"currency\\\":\\\"USD\\\"\\n    },\\n    \\\"extra\\\":{\\n      \\\"ip\\\":\\\"192.168.0.1\\\"\\n    }\\n}' \\\"https://sandbox.synapsepay.com/api/3/users/57e46e6f86c273634c237111/nodes/57e470b486c273634c237122/trans\\\"\",\n      \"language\": \"curl\"\n    },\n    {\n      \"code\": \"{\\n  \\\"_id\\\": \\\"57e4730d86c2733736c13384\\\",\\n  \\\"_links\\\": {\\n    \\\"self\\\": {\\n      \\\"href\\\": \\\"https://sandbox.synapsepay.com/api/3/users/57e46e6f86c273634c237111/nodes/57e470b486c273634c237122/trans/57e4730d86c2733736c13384\\\"\\n    }\\n  },\\n  \\\"amount\\\": {\\n    \\\"amount\\\": 1000,\\n    \\\"currency\\\": \\\"USD\\\"\\n  },\\n  \\\"client\\\": {\\n    \\\"id\\\": 844,\\n    \\\"name\\\": \\\"SynapsePay*Sandbox\\\"\\n  },\\n  \\\"extra\\\": {\\n    \\\"created_on\\\": 1474589452338,\\n    \\\"ip\\\": \\\"192.168.0.1\\\",\\n    \\\"latlon\\\": \\\"0,0\\\",\\n    \\\"note\\\": \\\"\\\",\\n    \\\"process_on\\\": 1474589452389,\\n    \\\"supp_id\\\": \\\"\\\",\\n    \\\"webhook\\\": \\\"\\\"\\n  },\\n  \\\"fees\\\": [\\n    {\\n      \\\"fee\\\": 0.2,\\n      \\\"note\\\": \\\"Synapse Facilitator Fee\\\",\\n      \\\"to\\\": {\\n        \\\"id\\\": \\\"559339aa86c273605ccd35df\\\"\\n      }\\n    }\\n  ],\\n  \\\"from\\\": {\\n    \\\"id\\\": \\\"57e470b486c273634c237122\\\",\\n    \\\"nickname\\\": \\\"Platform X's Synapse Account\\\",\\n    \\\"type\\\": \\\"SYNAPSE-US\\\",\\n    \\\"user\\\": {\\n      \\\"_id\\\": \\\"57e46e6f86c273634c237111\\\",\\n      \\\"legal_names\\\": [\\n        \\\"Platform X\\\"\\n      ]\\n    }\\n  },\\n  \\\"recent_status\\\": {\\n    \\\"date\\\": 1474589452337,\\n    \\\"note\\\": \\\"Transaction created\\\",\\n    \\\"status\\\": \\\"CREATED\\\",\\n    \\\"status_id\\\": \\\"1\\\"\\n  },\\n  \\\"timeline\\\": [\\n    {\\n      \\\"date\\\": 1474589452337,\\n      \\\"note\\\": \\\"Transaction created\\\",\\n      \\\"status\\\": \\\"CREATED\\\",\\n      \\\"status_id\\\": \\\"1\\\"\\n    }\\n  ],\\n  \\\"to\\\": {\\n    \\\"id\\\": \\\"57e46c6086c273634c2370f2\\\",\\n    \\\"nickname\\\": \\\"Fake Account\\\",\\n    \\\"type\\\": \\\"ACH-US\\\",\\n    \\\"user\\\": {\\n      \\\"_id\\\": \\\"57e468f086c2733736c13314\\\",\\n      \\\"legal_names\\\": [\\n        \\\"Bryan Keltner\\\"\\n      ]\\n    }\\n  }\\n}\",\n      \"language\": \"json\",\n      \"name\": \"Response\"\n    },\n    {\n      \"code\": \"// Node.js API Initialization (https://docs.synapsepay.com/docs/api-initialization)\\n\\nlet platformX;\\nlet options = {\\n  _id: USER_ID,\\n  fingerprint: USER_FINGERPRINT,\\n  ip_address: Helpers.getUserIP()\\n};\\n\\nUsers.get(\\n  client,\\n  options,\\n  function(err, userObj) {\\n    platformX = userObj;\\n  }\\n);\\n\\nlet platformXnode;\\n// Get Platform X's node\\nNodes.get(\\n  platformX,\\n  {\\n    _id: '57e470b486c273634c237122'\\n  },\\n  function(err, nodeResponse) {\\n    platformXnode = nodeResponse;\\n  }\\n);\\n\\nconst transPayload = {\\n  \\\"to\\\": {\\n    \\\"type\\\":\\\"ACH-US\\\",\\n    \\\"id\\\":\\\"57e46c6086c273634c2370f2\\\"\\n  },\\n  \\\"amount\\\": {\\n    \\\"amount\\\":1000,\\n    \\\"currency\\\":\\\"USD\\\"\\n  },\\n  \\\"extra\\\":{\\n    \\\"ip\\\":\\\"192.168.0.1\\\"\\n  }\\n};\\n\\nTransactions.create(\\n  platformXnode, // from node\\n  transPayload,\\n  function(err, transactionResp) {\\n    // handle error or transaction object\\n  }\\n);\",\n      \"language\": \"javascript\",\n      \"name\": \"Node.js\"\n    }\n  ]\n}\n[/block]\nThat's it! Now you have a basic payout application working with Synapse. This is pretty bare bones obviously. You can customize your CIP, use [Subscriptions](doc:subscriptions) etc to improve your integration even more.\n\nIf you have any questions, please [Contact us](doc:contact-us) and we will be more than happy to assist.","excerpt":"Common Flow for Marketplace Platforms","slug":"payout-flow","type":"basic","title":"Payout Flow"}

Payout Flow

Common Flow for Marketplace Platforms

One of the most common flows with Synapse is a payout flow. This is used by platforms that wish to send payments to individuals/businesses via their account. So something as follows: [block:image] { "images": [ { "image": [ "https://files.readme.io/7702fc1-Untitled_Diagram_8.png", "Untitled Diagram (8).png", 343, 63, "#171717" ], "border": false, "sizing": "smart", "caption": "Platform X wants to send a payout to Bryan for payroll once every two weeks." } ] } [/block] In this instance, the first thing the platform needs to do is [create](doc:create-a-user) a user account for Bryan in Synapse's system & make sure that the [platform has a `SYNAPSE-US` node created](https://help.synapsepay.com/hc/en-us/articles/216269798-Add-a-Bank-Account-on-the-Dashboard-Wire-Synapse-IOU-accounts). ### Create account for Bryan: [block:code] { "codes": [ { "code": "curl -X POST -H \"Content-Type: application/json\" -H \"X-SP-GATEWAY: e3f19e4bd4022c86e7f2|11c94ba6bad74d24a0158bc707f0fc19a86dc08f\" -H \"X-SP-USER-IP: 107.170.246.225\" -H \"X-SP-USER: |e716990e50b67a1177736960b6357524b22090ccab093d068b3d7a18dbde3f4c\" -d '{\n \"logins\": [\n {\n \"email\": \"bryan@test.com\"\n }\n ],\n \"phone_numbers\": [\n \"901.942.8167\"\n ],\n \"legal_names\": [\n \"Bryan Keltner\"\n ],\n \"extra\": {\n \"note\": \"Synapse account for Bryan Keltner\"\n }\n}' \"https://sandbox.synapsepay.com/api/3/users\"", "language": "curl" }, { "code": "{\n \"_id\": \"57e468f086c2733736c13314\",\n \"_links\": {\n \"self\": {\n \"href\": \"https://sandbox.synapsepay.com/api/3/users/57e468f086c2733736c13314\"\n }\n },\n \"client\": {\n \"id\": 844,\n \"name\": \"SynapsePay*Sandbox\"\n },\n \"doc_status\": {\n \"physical_doc\": \"MISSING|INVALID\",\n \"virtual_doc\": \"MISSING|INVALID\"\n },\n \"documents\": [],\n \"extra\": {\n \"cip_tag\": 1,\n \"date_joined\": 1474586864860,\n \"extra_security\": true,\n \"is_business\": false,\n \"supp_id\": \"\"\n },\n \"is_hidden\": false,\n \"legal_names\": [\n \"Bryan Keltner\"\n ],\n \"logins\": [\n {\n \"email\": \"bryan@test.com\",\n \"scope\": \"READ_AND_WRITE\"\n }\n ],\n \"permission\": \"UNVERIFIED\",\n \"phone_numbers\": [\n \"901.942.8167\"\n ],\n \"photos\": [],\n \"refresh_token\": \"refresh-3a09773f-388e-472b-ad1e-fccba7c2f152\"\n}", "language": "json", "name": "Response" }, { "code": "const SynapsePay = require('synapsepay'); \nconst Clients = SynapsePay.Clients;\nconst Helpers = SynapsePay.Helpers;\nconst Users = SynapsePay.Users;\n\nconst client = new Clients(\n 'YOUR_CLIENT_ID',\n 'YOUR_CLIENT_SECRET',\n IS_PRODUCTION # boolean\n);\n\nconst userInfo = {\n logins: [\n {\n email: 'bryan@test.com'\n }\n ],\n phone_numbers: [\n '901.942.8167'\n ],\n legal_names: [\n 'Bryan Keltner'\n ],\n extra: {\n note: 'Synapse account for Bryan Keltner'\n }\n};\n\nlet bryan;\n\nUsers.create(\n client,\n // fingerprint (specific to user or static for application)\n process.env.FINGERPRINT,\n Helpers.getUserIP(),\n userInfo,\n function(err, userObj) {\n // store Bryan's info so we can access it in the future\n bryan = userObj; \n }\n);", "language": "javascript", "name": "Node.js" } ] } [/block] In the response, you get back an `_id` associated with Bryan. You should store this `_id`, as this will be used in the future to access Bryan's account. You should also notice that currently Bryan's account `permission` is `UNVERIFIED`. For Bryan to be able to receive funds, his permission at least needs to be `RECEIVE`. To be able to get there, we would need to add some KYC info to Bryan's account. Synapse is very versatile and can recognize over [3,000 unique KYC flows](https://medium.com/@sankaet/kyc-2-0-69d4d1acdc6d). For the purpose of this tutorial, we will assume for Bryan to be able to get `RECEIVE` permissions, we need to supply Bryan's SSN number. To submit this information, I first need to [OAuth](doc:get-oauth_key-refresh-token) Bryan & then [PATCH](doc:adding-documents) his account with the appropriate KYC information. ### OAuth Bryan: If you are using one of the Client libraries, this step is not required because the libraries automatically handle OAuth after the user is created. [block:code] { "codes": [ { "code": "curl -X POST -H \"Content-Type: application/json\" -H \"X-SP-GATEWAY: e3f19e4bd4022c86e7f2|11c94ba6bad74d24a0158bc707f0fc19a86dc08f\" -H \"X-SP-USER-IP: 107.170.246.225\" -H \"X-SP-USER: |e716990e50b67a1177736960b6357524b22090ccab093d068b3d7a18dbde3f4c\" -d '{\n \"refresh_token\": \"refresh-3a09773f-388e-472b-ad1e-fccba7c2f152\"\n}' \"https://sandbox.synapsepay.com/api/3/oauth/57e468f086c2733736c13314\"", "language": "curl" }, { "code": "{\n \"expires_at\": \"1474594065\",\n \"expires_in\": \"7117\",\n \"oauth_key\": \"oauth-e8115f89-0153-4162-b024-36669ece4796\",\n \"refresh_expires_in\": 19,\n \"refresh_token\": \"refresh-3a09773f-388e-472b-ad1e-fccba7c2f152\"\n}", "language": "json", "name": "Response" } ] } [/block] From the response, we need to grab the `oauth_key` to make further requests on the user's behalf. ### KYC Bryan: [block:code] { "codes": [ { "code": "curl -X PATCH -H \"Content-Type: application/json\" -H \"X-SP-GATEWAY: e3f19e4bd4022c86e7f2|11c94ba6bad74d24a0158bc707f0fc19a86dc08f\" -H \"X-SP-USER-IP: 107.170.246.225\" -H \"X-SP-USER: oauth-e8115f89-0153-4162-b024-36669ece4796|e716990e50b67a1177736960b6357524b22090ccab093d068b3d7a18dbde3f4c\" -d '{\n \"documents\":[{\n \"email\":\"bryan@test.com\",\n \"phone_number\":\"901-942-8167\",\n \"ip\":\"101.110.226.221\",\n \"name\":\"Bryan Keltner\",\n \"alias\":\"Giggle\",\n \"entity_type\":\"M\",\n \"entity_scope\":\"Arts & Entertainment\",\n \"day\":2,\n \"month\":5,\n \"year\":1989,\n \"address_street\":\"4480 20th St\",\n \"address_city\":\"SF\",\n \"address_subdivision\":\"CA\",\n \"address_postal_code\":\"94114\",\n \"address_country_code\":\"US\",\n \"virtual_docs\":[{\n \"document_value\":\"111-1111-2222\",\n \"document_type\":\"SSN\"\n }]\n }]\n}' \"https://sandbox.synapsepay.com/api/3/users/57e468f086c2733736c13314\"", "language": "curl" }, { "code": "{\n \"_id\": \"57e468f086c2733736c13314\",\n \"_links\": {\n \"self\": {\n \"href\": \"https://sandbox.synapsepay.com/api/3/users/57e468f086c2733736c13314\"\n }\n },\n \"client\": {\n \"id\": 844,\n \"name\": \"SynapsePay*Sandbox\"\n },\n \"doc_status\": {\n \"physical_doc\": \"MISSING|INVALID\",\n \"virtual_doc\": \"SUBMITTED|VALID\"\n },\n \"documents\": [\n {\n \"id\": \"24fa1c3928a05354394bfa8bca6e876c05626bd540df41d8f870e6c3b544103f\",\n \"name\": \"Bryan Keltner\",\n \"permission_scope\": \"RECEIVE|1000|DAILY\",\n \"physical_docs\": [],\n \"social_docs\": [\n {\n \"document_type\": \"EMAIL\",\n \"id\": \"dd641c721c5c23ec66c3d27216dda6a85ce87b2f6717995c90b20eb69659f814\",\n \"last_updated\": 1474587319968,\n \"status\": \"SUBMITTED|VALID\"\n },\n {\n \"document_type\": \"PHONE_NUMBER\",\n \"id\": \"9dd593112385cfed22721355d279e79d33acd2c48cffe9c007b6c4acbfde826c\",\n \"last_updated\": 1474587320325,\n \"status\": \"SUBMITTED|VALID\"\n }\n ],\n \"virtual_docs\": [\n {\n \"document_type\": \"SSN\",\n \"id\": \"633c0873b9fc5acce12c2028b4324059d348bcfaffd661be7c405e5ed27a72a8\",\n \"last_updated\": 1474587320679,\n \"status\": \"SUBMITTED|VALID\"\n }\n ]\n }\n ],\n \"extra\": {\n \"cip_tag\": 1,\n \"date_joined\": 1474586864860,\n \"extra_security\": true,\n \"is_business\": false,\n \"supp_id\": \"\"\n },\n \"is_hidden\": false,\n \"legal_names\": [\n \"Bryan Keltner\"\n ],\n \"logins\": [\n {\n \"email\": \"bryan@test.com\",\n \"scope\": \"READ_AND_WRITE\"\n }\n ],\n \"permission\": \"RECEIVE\",\n \"phone_numbers\": [\n \"901.942.8167\"\n ],\n \"photos\": [],\n \"refresh_token\": \"refresh-3a09773f-388e-472b-ad1e-fccba7c2f152\"\n}", "language": "json", "name": "Response" }, { "code": "const documents = {\n \"documents\":[{\n \"email\":\"bryan@test.com\",\n \"phone_number\":\"901-942-8167\",\n \"ip\":\"101.110.226.221\",\n \"name\":\"Bryan Keltner\",\n \"alias\":\"Giggle\",\n \"entity_type\":\"M\",\n \"entity_scope\":\"Arts & Entertainment\",\n \"day\":2,\n \"month\":5,\n \"year\":1989,\n \"address_street\":\"4480 20th St\",\n \"address_city\":\"SF\",\n \"address_subdivision\":\"CA\",\n \"address_postal_code\":\"94114\",\n \"address_country_code\":\"US\",\n \"virtual_docs\":[{\n \"document_value\":\"111-1111-2222\",\n \"document_type\":\"SSN\"\n }]\n }]\n};\n\nbryan.addDocuments(\n documents,\n function(err, userObj) {\n // update Bryan's info to include documents\n bryan = userObj;\n }\n);", "language": "javascript", "name": "Node.js" } ] } [/block] As you can see from the response now, Bryan has `RECEIVE` permissions. Also its worth noting that the `permission_scope` in his document is `RECEIVE|1000|DAILY`. Which means, Bryan can receive payments up to $1,000 daily. Again, all of this is customizable per platform. So you can always tweak your rules around daily or month limits or even what KYC needs to be submitted per user. Now Bryan's profile has been verified. We still however need to connect Bryan's bank account with his profile. To be able to do that, we will use [Nodes POST](doc:add-ach-us-node) API call. In this API call we can either use [account & routing number](doc:add-ach-us-node-via-acrt-s) to create an account or use [bank login credentials](doc:add-ach-us-node). In case of Bryan, we will use the [account & routing number](doc:add-ach-us-node-via-acrt-s) method. ### Link Bryan's bank account [block:code] { "codes": [ { "code": "curl -X POST -H \"Content-Type: application/json\" -H \"X-SP-GATEWAY: e3f19e4bd4022c86e7f2|11c94ba6bad74d24a0158bc707f0fc19a86dc08f\" -H \"X-SP-USER-IP: 107.170.246.225\" -H \"X-SP-USER: oauth-e8115f89-0153-4162-b024-36669ece4796|e716990e50b67a1177736960b6357524b22090ccab093d068b3d7a18dbde3f4c\" -d '{\n \"type\": \"ACH-US\",\n \"info\": {\n \"nickname\": \"Fake Account\",\n \"account_num\": \"23456543234567543234567\",\n \"routing_num\": \"051000017\",\n \"type\": \"PERSONAL\",\n \"class\": \"CHECKING\"\n }\n}' \"https://sandbox.synapsepay.com/api/3/users/57e468f086c2733736c13314/nodes\"", "language": "curl" }, { "code": "{\n \"error_code\": \"0\",\n \"http_code\": \"200\",\n \"nodes\": [\n {\n \"_id\": \"57e46c6086c273634c2370f2\",\n \"_links\": {\n \"self\": {\n \"href\": \"https://sandbox.synapsepay.com/api/3/users/57e468f086c2733736c13314/nodes/57e46c6086c273634c2370f2\"\n }\n },\n \"allowed\": \"CREDIT\",\n \"extra\": {\n \"supp_id\": null\n },\n \"info\": {\n \"account_num\": \"4567\",\n \"bank_long_name\": \"BANK OF AMERICA, N.A.\",\n \"class\": \"CHECKING\",\n \"name_on_account\": \"Bryan Keltner\",\n \"nickname\": \"Fake Account\",\n \"routing_num\": \"0017\",\n \"type\": \"PERSONAL\"\n },\n \"is_active\": true,\n \"type\": \"ACH-US\"\n }\n ],\n \"success\": true\n}", "language": "json", "name": "Response" }, { "code": "const Nodes = SynapsePay.Nodes;\n\nconst achPayload = {\n type: \"ACH-US\",\n info: {\n nickname: \"Fake Account\",\n account_num: \"23456543234567543234567\",\n routing_num: \"051000017\",\n type: \"PERSONAL\",\n class: \"CHECKING\"\n }\n};\n\nlet bryansBank;\n\nNodes.create(\n bryan,\n achPayload,\n function(err, nodes) {\n bryansBank = nodes[0];\n }\n);", "language": "javascript", "name": "Node.js" } ] } [/block] The response gives us the `_id` of the bank account we just linked with Bryan's account. Another thing worth noting here is the `allowed` property of the node. Currently its `CREDIT`. Since Bryan is only receiving funds, this status will do. The next step is for us to create a transaction going from Platform X's `SYNAPSE-US` account to Bryan's `ACH-US` account. ### Create Transaction Since the sender is Platform X, we need to get Platform X's `oauth_key` to be able to initiate this transaction. Either we can use the existing `oauth_key` or just [OAuth](doc:get-oauth_key-refresh-token) Platform X again. Once we have the most recent `oauth_key`, we can create the transaction via [Transactions POST](doc:create-transaction) API call. We will also need Bryan's `ACH-US` node `_id` for this, but that can be grabbed easily from the dashboard. [block:code] { "codes": [ { "code": "curl -X POST -H \"Content-Type: application/json\" -H \"X-SP-GATEWAY: e3f19e4bd4022c86e7f2|11c94ba6bad74d24a0158bc707f0fc19a86dc08f\" -H \"X-SP-USER-IP: 107.170.246.225\" -H \"X-SP-USER: oauth-e8115f89-0153-4162-b024-36669ece4796|e716990e50b67a1177736960b6357524b22090ccab093d068b3d7a18dbde3f4c\" -H \"X-SP-IDEMPOTENCY-KEY: a938b7083253972554ce8e9dd5eb4e86e271b2a346d52ad136eccd21606d6299\" -d '{\n \"to\":{\n \"type\":\"ACH-US\",\n \"id\":\"57e46c6086c273634c2370f2\"\n },\n \"amount\":{\n \"amount\":1000,\n \"currency\":\"USD\"\n },\n \"extra\":{\n \"ip\":\"192.168.0.1\"\n }\n}' \"https://sandbox.synapsepay.com/api/3/users/57e46e6f86c273634c237111/nodes/57e470b486c273634c237122/trans\"", "language": "curl" }, { "code": "{\n \"_id\": \"57e4730d86c2733736c13384\",\n \"_links\": {\n \"self\": {\n \"href\": \"https://sandbox.synapsepay.com/api/3/users/57e46e6f86c273634c237111/nodes/57e470b486c273634c237122/trans/57e4730d86c2733736c13384\"\n }\n },\n \"amount\": {\n \"amount\": 1000,\n \"currency\": \"USD\"\n },\n \"client\": {\n \"id\": 844,\n \"name\": \"SynapsePay*Sandbox\"\n },\n \"extra\": {\n \"created_on\": 1474589452338,\n \"ip\": \"192.168.0.1\",\n \"latlon\": \"0,0\",\n \"note\": \"\",\n \"process_on\": 1474589452389,\n \"supp_id\": \"\",\n \"webhook\": \"\"\n },\n \"fees\": [\n {\n \"fee\": 0.2,\n \"note\": \"Synapse Facilitator Fee\",\n \"to\": {\n \"id\": \"559339aa86c273605ccd35df\"\n }\n }\n ],\n \"from\": {\n \"id\": \"57e470b486c273634c237122\",\n \"nickname\": \"Platform X's Synapse Account\",\n \"type\": \"SYNAPSE-US\",\n \"user\": {\n \"_id\": \"57e46e6f86c273634c237111\",\n \"legal_names\": [\n \"Platform X\"\n ]\n }\n },\n \"recent_status\": {\n \"date\": 1474589452337,\n \"note\": \"Transaction created\",\n \"status\": \"CREATED\",\n \"status_id\": \"1\"\n },\n \"timeline\": [\n {\n \"date\": 1474589452337,\n \"note\": \"Transaction created\",\n \"status\": \"CREATED\",\n \"status_id\": \"1\"\n }\n ],\n \"to\": {\n \"id\": \"57e46c6086c273634c2370f2\",\n \"nickname\": \"Fake Account\",\n \"type\": \"ACH-US\",\n \"user\": {\n \"_id\": \"57e468f086c2733736c13314\",\n \"legal_names\": [\n \"Bryan Keltner\"\n ]\n }\n }\n}", "language": "json", "name": "Response" }, { "code": "// Node.js API Initialization (https://docs.synapsepay.com/docs/api-initialization)\n\nlet platformX;\nlet options = {\n _id: USER_ID,\n fingerprint: USER_FINGERPRINT,\n ip_address: Helpers.getUserIP()\n};\n\nUsers.get(\n client,\n options,\n function(err, userObj) {\n platformX = userObj;\n }\n);\n\nlet platformXnode;\n// Get Platform X's node\nNodes.get(\n platformX,\n {\n _id: '57e470b486c273634c237122'\n },\n function(err, nodeResponse) {\n platformXnode = nodeResponse;\n }\n);\n\nconst transPayload = {\n \"to\": {\n \"type\":\"ACH-US\",\n \"id\":\"57e46c6086c273634c2370f2\"\n },\n \"amount\": {\n \"amount\":1000,\n \"currency\":\"USD\"\n },\n \"extra\":{\n \"ip\":\"192.168.0.1\"\n }\n};\n\nTransactions.create(\n platformXnode, // from node\n transPayload,\n function(err, transactionResp) {\n // handle error or transaction object\n }\n);", "language": "javascript", "name": "Node.js" } ] } [/block] That's it! Now you have a basic payout application working with Synapse. This is pretty bare bones obviously. You can customize your CIP, use [Subscriptions](doc:subscriptions) etc to improve your integration even more. If you have any questions, please [Contact us](doc:contact-us) and we will be more than happy to assist.