{"metadata":{"image":[],"title":"","description":""},"api":{"url":"","auth":"required","settings":"","results":{"codes":[]},"params":[],"examples":{"codes":[]}},"next":{"description":"","pages":[]},"title":"Wallet Callbacks","type":"basic","slug":"callbacks-1","excerpt":"","body":"We provide a series of HTTP callbacks that allow you to notify users when funds have been deposited and when they become available. When [creating a wallet](doc:create-wallet), you can set a `callbackUrl.` The following information describes the structure of the callbacks received.\n\n###When callbacks are sent\nCallbacks are sent whenever a transactional event occurs that will affect the wallet's balance. Examples include:\n* Incoming pending transaction\n* Pending transaction confirmed\n* Outgoing transaction\nYou may receive two callbacks for a single transaction. This is especially true for transactions on the blockchain. In these cases, you would receive one callback when the transaction is first observed and one callback once the transaction is confirmed.\n\n###Callback Acceptance and Retries\nYour system should respond to the callback request with a 200 response. We only attempt to send the request once, but we may introduce automatic retries in the future. We can manually resend callbacks upon request.\n\n###Payload\nThe callback payload will be a JSON representation of the transaction that has caused the callback to trigger. An example of such a transaction can be found below:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"//Incoming BTC deposit from external BTC wallet.\\n{\\n  \\\"createdAt\\\": 1613027293110,\\n  \\\"id\\\": \\\"TR_7NVXRFRBZJV\\\",\\n  \\\"source\\\": \\\"bitcoin:EXTERNAL\\\",\\n  \\\"dest\\\": \\\"wallet:WA_8AFWHMHLYXH\\\",\\n  \\\"currency\\\": \\\"BTC\\\",\\n  \\\"amount\\\": 0.01653538,\\n  \\\"status\\\": \\\"CONFIRMED\\\",\\n  \\\"confirmedAt\\\": 1613027293110,\\n  \\\"cancelledAt\\\": null,\\n  \\\"reversedAt\\\": null,\\n  \\\"message\\\": null,\\n  \\\"allowOverdraft\\\": true,\\n  \\\"authorizer\\\": null,\\n  \\\"senderProvidedId\\\": null,\\n  \\\"reversedBy\\\": null,\\n  \\\"fees\\\": 0,\\n  \\\"feesDest\\\": null,\\n  \\\"metadata\\\": {\\n    \\\"BTCNetworkTxId\\\": \\\"9689d7c675b05f71629696ea9b25c2d61f52406598a4bef759f782c2c35d4f0c\\\"\\n  },\\n  \\\"tags\\\": [],\\n  \\\"destFees\\\": null,\\n  \\\"sourceFees\\\": null\\n}\",\n      \"language\": \"json\",\n      \"name\": \"BTC Deposit Example\"\n    },\n    {\n      \"code\": \"//Incoming ETH deposit from external ETH wallet.\\n{\\n  \\\"createdAt\\\": 1614721011262,\\n  \\\"id\\\": \\\"TR_V8WQDC27BX8\\\",\\n  \\\"source\\\": \\\"ethereum:0x003bbce1eac59b406dd0e143e856542df3659075\\\",\\n  \\\"dest\\\": \\\"wallet:WA_3FE7HZHCYBG\\\",\\n  \\\"currency\\\": \\\"ETH\\\",\\n  \\\"amount\\\": 6,\\n  \\\"status\\\": \\\"CONFIRMED\\\",\\n  \\\"confirmedAt\\\": 1614721011262,\\n  \\\"cancelledAt\\\": null,\\n  \\\"reversedAt\\\": null,\\n  \\\"message\\\": null,\\n  \\\"allowOverdraft\\\": true,\\n  \\\"authorizer\\\": null,\\n  \\\"senderProvidedId\\\": null,\\n  \\\"reversedBy\\\": null,\\n  \\\"fees\\\": 0,\\n  \\\"feesDest\\\": null,\\n  \\\"metadata\\\": {\\n    \\\"ETHNetworkTxId\\\": \\\"0x816091d7fd5fe99b6b9f5cefafe01a39e0c4aca6b44e6d8ee32164b6097ea5d6\\\"\\n  },\\n  \\\"tags\\\": [],\\n  \\\"sourceFees\\\": null,\\n  \\\"destFees\\\": null\\n}\",\n      \"language\": \"json\",\n      \"name\": \"ETH Deposit Example\"\n    },\n    {\n      \"code\": \"// Interest payouts require resolving the transfer id.\\n// GET https://api.testwyre.com/v3/transfers/TF_HTQEQ327NYE\\n{\\n  \\\"createdAt\\\": 1617235219704,\\n  \\\"id\\\": \\\"TR_AE79Q7L6QAT\\\",\\n  \\\"source\\\": \\\"transfer:TF_HTQEQ327NYE\\\",\\n  \\\"dest\\\": \\\"wallet:WA_8TJFJ3EQEN9\\\",\\n  \\\"currency\\\": \\\"BTC\\\",\\n  \\\"amount\\\": 0.0000106,\\n  \\\"status\\\": \\\"CONFIRMED\\\",\\n  \\\"confirmedAt\\\": 1617235219704,\\n  \\\"cancelledAt\\\": null,\\n  \\\"reversedAt\\\": null,\\n  \\\"message\\\": \\\"Deposit for transfer TF_HTQEQ327NYE\\\",\\n  \\\"allowOverdraft\\\": true,\\n  \\\"authorizer\\\": \\\"service:Nobody\\\",\\n  \\\"senderProvidedId\\\": null,\\n  \\\"reversedBy\\\": null,\\n  \\\"fees\\\": 0,\\n  \\\"feesDest\\\": null,\\n  \\\"metadata\\\": {\\n    \\\"transferId\\\": \\\"TF_HTQEQ327NYE\\\"\\n  },\\n  \\\"tags\\\": [],\\n  \\\"sourceFees\\\": null,\\n  \\\"destFees\\\": null\\n}\",\n      \"language\": \"json\",\n      \"name\": \"Interest Payout Example\"\n    }\n  ]\n}\n[/block]\n\n###Security Signature\nIn order to prevent callback spoofing, we provide a signature with the callback passed back through the HTTP header X-API-Signature.\n\ni.e. x-api-signature: `56a00765528a6a6fab70c9272485131f157a423f78a5ab06d2c8627f867f6aea `\n\nThis signature is a SHA256 HMAC signature of the JSON body signed with the merchant's secret key. To the right you can find example implementations of the signature.\n\nNote: It's important to verify the signature in the callback, otherwise it is possible for the request to be spoofed by an external attacker.\n[block:api-header]\n{\n  \"title\": \"Interest Payouts and Account Sources\"\n}\n[/block]\nCertain types of transfers will display the \"source\" as a transfer [SRN](doc:srns). This requires that you query the transfer id to get the details of the transfer. This is the case for savings wallets and subsequent interest payouts.\n\nYou can determine if a callback is the result of an interest payout by querying the transfer id in the \"source,\" for example:\n\nIf a callback presents with a source like this:  \"source\": \"transfer:TF_HTQEQ327NYE,\" you can query the transfer id with GET https://api.testwyre.com/v3/transfers/TF_HTQEQ327NYE. The result will look like the sample below. Notice the source of the transfer: \"source\": \"service:Interest Payments\",\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n    \\\"owner\\\": \\\"service:Nobody\\\",\\n    \\\"status\\\": \\\"COMPLETED\\\",\\n    \\\"source\\\": \\\"service:Interest Payments\\\",\\n    \\\"createdAt\\\": 1617235217000,\\n    \\\"sourceAmount\\\": 0.0000106,\\n    \\\"destCurrency\\\": \\\"BTC\\\",\\n    \\\"sourceCurrency\\\": \\\"BTC\\\",\\n    \\\"totalFees\\\": 0,\\n    \\\"customId\\\": null,\\n    \\\"completedAt\\\": 1617235220000,\\n    \\\"cancelledAt\\\": null,\\n    \\\"failureReason\\\": null,\\n    \\\"expiresAt\\\": 1617494417000,\\n    \\\"updatedAt\\\": 1617235220000,\\n    \\\"fees\\\": {\\n        \\\"BTC\\\": 0E-8\\n    },\\n    \\\"destAmount\\\": 0.0000106,\\n    \\\"exchangeRate\\\": null,\\n    \\\"statusHistories\\\": [\\n        {\\n            \\\"id\\\": \\\"BBGZBGDVWUR\\\",\\n            \\\"transferId\\\": \\\"TF_HTQEQ327NYE\\\",\\n            \\\"createdAt\\\": 1617235220000,\\n            \\\"type\\\": \\\"ADMIN_CREDIT\\\",\\n            \\\"statusOrder\\\": 0,\\n            \\\"statusDetail\\\": \\\"Initiating Transfer\\\",\\n            \\\"state\\\": \\\"INITIATED\\\",\\n            \\\"failedState\\\": null\\n        },\\n        {\\n            \\\"id\\\": \\\"GUMTCX4QUEH\\\",\\n            \\\"transferId\\\": \\\"TF_HTQEQ327NYE\\\",\\n            \\\"createdAt\\\": 1617235220000,\\n            \\\"type\\\": \\\"ADMIN_CREDIT\\\",\\n            \\\"statusOrder\\\": 5100,\\n            \\\"statusDetail\\\": \\\"Transfer Completed\\\",\\n            \\\"state\\\": \\\"COMPLETED\\\",\\n            \\\"failedState\\\": null\\n        }\\n    ],\\n    \\\"estimatedArrival\\\": 1617847722127,\\n    \\\"dest\\\": \\\"wallet:WA_8TJFJ3EQEN9\\\",\\n    \\\"pendingSubStatus\\\": null,\\n    \\\"blockchainTx\\\": null,\\n    \\\"reversalReason\\\": null,\\n    \\\"reversingSubStatus\\\": null,\\n    \\\"message\\\": null,\\n    \\\"id\\\": \\\"TF_HTQEQ327NYE\\\"\\n}\",\n      \"language\": \"json\",\n      \"name\": \"Interest Transfer Details\"\n    }\n  ]\n}\n[/block]","updates":[],"order":1,"isReference":false,"hidden":false,"sync_unique":"","link_url":"","link_external":false,"_id":"6065f240e31637007f217646","createdAt":"2021-04-01T16:18:08.145Z","user":"5f7f6ea298ba660011771f74","category":{"sync":{"isSync":false,"url":""},"pages":[],"title":"Wallets","slug":"wallet","order":5,"from_sync":false,"reference":false,"_id":"5f276e5348d2b600321aef9b","createdAt":"2020-08-03T01:54:28.004Z","version":"550f75de61d9d30d00af9e01","project":"550f74bb6fc8130d0038aad3","__v":0},"version":{"version":"3","version_clean":"3.0.0","codename":"","is_stable":true,"is_beta":true,"is_hidden":false,"is_deprecated":false,"categories":["550f75de61d9d30d00af9e02","551027e38579861900a86698","551029e08579861900a8669a","551029e7498062190006328a","5bc633a722d682005c9ad9e4","5bc633b08c4b0b000d6a7eaa","5bc633b48f3ff600626e3e18","5bc63538e5a6ba000d22ee6d","5bc63587a18a6b000decd295","5bc635c0937fcb0056223d9c","5bc6360f42f41800319aeaa6","5be5d13ff1d319002baca9ce","5be5d2287cd14d00291fbfdb","5be8b3b09f7cb70023c56a39","5be8b3cbb910100044e20206","5c1d769a4f6aed001fe527f0","5c402942010f0d001496dded","5e8127d61c906800374eeb1c","5f2768c98622b8005106544a","5f2768d05702ca0011f7655e","5f276e5348d2b600321aef9b","5f276fd300e519001139200a","5f9a2cb79dafe500259281a7","5fd92bf362bb7301b00e48ba"],"_id":"550f75de61d9d30d00af9e01","__v":24,"releaseDate":"2015-03-23T02:09:34.221Z","project":"550f74bb6fc8130d0038aad3","createdAt":"2015-03-23T02:09:34.221Z","forked_from":"550f74bb6fc8130d0038aad6"},"project":"550f74bb6fc8130d0038aad3","__v":0,"parentDoc":null}
We provide a series of HTTP callbacks that allow you to notify users when funds have been deposited and when they become available. When [creating a wallet](doc:create-wallet), you can set a `callbackUrl.` The following information describes the structure of the callbacks received. ###When callbacks are sent Callbacks are sent whenever a transactional event occurs that will affect the wallet's balance. Examples include: * Incoming pending transaction * Pending transaction confirmed * Outgoing transaction You may receive two callbacks for a single transaction. This is especially true for transactions on the blockchain. In these cases, you would receive one callback when the transaction is first observed and one callback once the transaction is confirmed. ###Callback Acceptance and Retries Your system should respond to the callback request with a 200 response. We only attempt to send the request once, but we may introduce automatic retries in the future. We can manually resend callbacks upon request. ###Payload The callback payload will be a JSON representation of the transaction that has caused the callback to trigger. An example of such a transaction can be found below: [block:code] { "codes": [ { "code": "//Incoming BTC deposit from external BTC wallet.\n{\n \"createdAt\": 1613027293110,\n \"id\": \"TR_7NVXRFRBZJV\",\n \"source\": \"bitcoin:EXTERNAL\",\n \"dest\": \"wallet:WA_8AFWHMHLYXH\",\n \"currency\": \"BTC\",\n \"amount\": 0.01653538,\n \"status\": \"CONFIRMED\",\n \"confirmedAt\": 1613027293110,\n \"cancelledAt\": null,\n \"reversedAt\": null,\n \"message\": null,\n \"allowOverdraft\": true,\n \"authorizer\": null,\n \"senderProvidedId\": null,\n \"reversedBy\": null,\n \"fees\": 0,\n \"feesDest\": null,\n \"metadata\": {\n \"BTCNetworkTxId\": \"9689d7c675b05f71629696ea9b25c2d61f52406598a4bef759f782c2c35d4f0c\"\n },\n \"tags\": [],\n \"destFees\": null,\n \"sourceFees\": null\n}", "language": "json", "name": "BTC Deposit Example" }, { "code": "//Incoming ETH deposit from external ETH wallet.\n{\n \"createdAt\": 1614721011262,\n \"id\": \"TR_V8WQDC27BX8\",\n \"source\": \"ethereum:0x003bbce1eac59b406dd0e143e856542df3659075\",\n \"dest\": \"wallet:WA_3FE7HZHCYBG\",\n \"currency\": \"ETH\",\n \"amount\": 6,\n \"status\": \"CONFIRMED\",\n \"confirmedAt\": 1614721011262,\n \"cancelledAt\": null,\n \"reversedAt\": null,\n \"message\": null,\n \"allowOverdraft\": true,\n \"authorizer\": null,\n \"senderProvidedId\": null,\n \"reversedBy\": null,\n \"fees\": 0,\n \"feesDest\": null,\n \"metadata\": {\n \"ETHNetworkTxId\": \"0x816091d7fd5fe99b6b9f5cefafe01a39e0c4aca6b44e6d8ee32164b6097ea5d6\"\n },\n \"tags\": [],\n \"sourceFees\": null,\n \"destFees\": null\n}", "language": "json", "name": "ETH Deposit Example" }, { "code": "// Interest payouts require resolving the transfer id.\n// GET https://api.testwyre.com/v3/transfers/TF_HTQEQ327NYE\n{\n \"createdAt\": 1617235219704,\n \"id\": \"TR_AE79Q7L6QAT\",\n \"source\": \"transfer:TF_HTQEQ327NYE\",\n \"dest\": \"wallet:WA_8TJFJ3EQEN9\",\n \"currency\": \"BTC\",\n \"amount\": 0.0000106,\n \"status\": \"CONFIRMED\",\n \"confirmedAt\": 1617235219704,\n \"cancelledAt\": null,\n \"reversedAt\": null,\n \"message\": \"Deposit for transfer TF_HTQEQ327NYE\",\n \"allowOverdraft\": true,\n \"authorizer\": \"service:Nobody\",\n \"senderProvidedId\": null,\n \"reversedBy\": null,\n \"fees\": 0,\n \"feesDest\": null,\n \"metadata\": {\n \"transferId\": \"TF_HTQEQ327NYE\"\n },\n \"tags\": [],\n \"sourceFees\": null,\n \"destFees\": null\n}", "language": "json", "name": "Interest Payout Example" } ] } [/block] ###Security Signature In order to prevent callback spoofing, we provide a signature with the callback passed back through the HTTP header X-API-Signature. i.e. x-api-signature: `56a00765528a6a6fab70c9272485131f157a423f78a5ab06d2c8627f867f6aea ` This signature is a SHA256 HMAC signature of the JSON body signed with the merchant's secret key. To the right you can find example implementations of the signature. Note: It's important to verify the signature in the callback, otherwise it is possible for the request to be spoofed by an external attacker. [block:api-header] { "title": "Interest Payouts and Account Sources" } [/block] Certain types of transfers will display the "source" as a transfer [SRN](doc:srns). This requires that you query the transfer id to get the details of the transfer. This is the case for savings wallets and subsequent interest payouts. You can determine if a callback is the result of an interest payout by querying the transfer id in the "source," for example: If a callback presents with a source like this: "source": "transfer:TF_HTQEQ327NYE," you can query the transfer id with GET https://api.testwyre.com/v3/transfers/TF_HTQEQ327NYE. The result will look like the sample below. Notice the source of the transfer: "source": "service:Interest Payments", [block:code] { "codes": [ { "code": "{\n \"owner\": \"service:Nobody\",\n \"status\": \"COMPLETED\",\n \"source\": \"service:Interest Payments\",\n \"createdAt\": 1617235217000,\n \"sourceAmount\": 0.0000106,\n \"destCurrency\": \"BTC\",\n \"sourceCurrency\": \"BTC\",\n \"totalFees\": 0,\n \"customId\": null,\n \"completedAt\": 1617235220000,\n \"cancelledAt\": null,\n \"failureReason\": null,\n \"expiresAt\": 1617494417000,\n \"updatedAt\": 1617235220000,\n \"fees\": {\n \"BTC\": 0E-8\n },\n \"destAmount\": 0.0000106,\n \"exchangeRate\": null,\n \"statusHistories\": [\n {\n \"id\": \"BBGZBGDVWUR\",\n \"transferId\": \"TF_HTQEQ327NYE\",\n \"createdAt\": 1617235220000,\n \"type\": \"ADMIN_CREDIT\",\n \"statusOrder\": 0,\n \"statusDetail\": \"Initiating Transfer\",\n \"state\": \"INITIATED\",\n \"failedState\": null\n },\n {\n \"id\": \"GUMTCX4QUEH\",\n \"transferId\": \"TF_HTQEQ327NYE\",\n \"createdAt\": 1617235220000,\n \"type\": \"ADMIN_CREDIT\",\n \"statusOrder\": 5100,\n \"statusDetail\": \"Transfer Completed\",\n \"state\": \"COMPLETED\",\n \"failedState\": null\n }\n ],\n \"estimatedArrival\": 1617847722127,\n \"dest\": \"wallet:WA_8TJFJ3EQEN9\",\n \"pendingSubStatus\": null,\n \"blockchainTx\": null,\n \"reversalReason\": null,\n \"reversingSubStatus\": null,\n \"message\": null,\n \"id\": \"TF_HTQEQ327NYE\"\n}", "language": "json", "name": "Interest Transfer Details" } ] } [/block]