{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Webhooks","description":"Tyro Health Docs","keywords":"redocly developer portal, api portal starter, api reference docs","lang":"en-US","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"webhooks","__idx":0},"children":["Webhooks"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Providers will need to manually mark a claim as approved/paid in Tyro Health Online which will trigger a webhook event .Tyro Health supports the following events for each WorkCover Queensland transaction:"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"use-cases","__idx":1},"children":["Use cases"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Partners can use webhook event notifications to alert them:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["That an invoice has been approved (",{"$$mdtype":"Tag","name":"highlight","attributes":{"backgroundcolour":"grey","textcolour":"dark"},"children":["healthFundApprovedInvoice"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["That an invoice has been Paid  (",{"$$mdtype":"Tag","name":"highlight","attributes":{"backgroundcolour":"grey","textcolour":"dark"},"children":["healthFundPaidInvoice"]},"). This would be for WorkCover Queensland delayed decision transactions where the claim was approved."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["That an invoice has been rejected (",{"$$mdtype":"Tag","name":"highlight","attributes":{"backgroundcolour":"grey","textcolour":"dark"},"children":["healthFundRejectedInvoice "]},"). This would be for WorkCover Queensland delayed decision transactions where the claim was paid."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"steps-to-receive-webhooks","__idx":2},"children":["Steps to receive webhooks"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the webhooks attribute and provide:"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"numberlabel","attributes":{"number":"1"},"children":[" URL (This is usually transaction specific)"]}," ",{"$$mdtype":"Tag","name":"numberlabel","attributes":{"number":"2"},"children":[" webhook event: one of the above listed events "]}," ",{"$$mdtype":"Tag","name":"numberlabel","attributes":{"number":"3"},"children":[" method: ",{"$$mdtype":"Tag","name":"highlight","attributes":{"backgroundcolour":"green"},"children":["POST/GET/PUT/DELETE"]}," "]}," ",{"$$mdtype":"Tag","name":"numberlabel","attributes":{"number":"4"},"children":["Any required headers "]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"example","__idx":3},"children":["Example"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"js","header":{"controls":{"copy":{}}},"source":"\nmedipassTransactionSDK.renderCreateTransaction({\n  ...\n  webhooks: [\n    {\n      url: 'https://your-site.com/transactions/your-transactionId/approved',\n      event: 'healthFundApprovedInvoice',\n      method: 'POST',\n      headers: { sessionKey: 'your required header' }\n    },\n    {\n      url: 'https://your-site.com/transactions/your-transactionId/paid',\n      event: 'healthFundPaidInvoice',\n      method: 'POST',\n      headers: { sessionKey: 'your required header' }\n    },\n    {\n      url: 'https://your-site.com/transactions/your-transactionId/rejected',\n      event: 'healthFundRejectedInvoice',\n      method: 'POST',\n      headers: { sessionKey: 'your required header' }\n    }\n  ]\n\n  \n  ...\n})\n\n","lang":"js"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["or"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"js","header":{"controls":{"copy":{}}},"source":"\nmedipassTransactionSDK.renderCreateTransaction({\n  ...\n  webhooks: [\n    {\n      url: 'https://your-site.com/transactions/your-transactionId/event-triggers',\n      event: 'healthFundApprovedInvoice,healthFundPaidInvoice,healthFundRejectedInvoice',\n      method: 'POST',\n      headers: { sessionKey: 'your required header' }\n    }\n  ]\n  ...\n})\n\n\n","lang":"js"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"event-handling","__idx":4},"children":["Event handling"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"retries","__idx":5},"children":["Retries"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["We will attempt to retry failed webhooks if a timeout or '500' response is received from your endpoint. Retries are performed every 15 minutes for up to 24 hours or until a successful response is received.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"sequencing--ordering","__idx":6},"children":["Sequencing & ordering"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["We do not guarantee delivery of webhook events in the order in which they are generated. Although it is rare, payment and invoice status events could be received out of sequence.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To handle this, we suggest to use the modified timestamp to determine if an update to status is appropriate for a given transaction. Alternatively, you can use our ",{"$$mdtype":"Tag","name":"highlight","attributes":{"backgroundcolour":"babyblue"},"children":["GET"]},"  Invoice API to determine to current status.",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"webhook-signature-optional","__idx":7},"children":["Webhook signature (optional)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To enhance the webhook security further, we support signing the payload with SHA-256 hmac signature for each of the ",{"$$mdtype":"Tag","name":"highlight","attributes":{"backgroundcolour":"green"},"children":["POST"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<base-url>/v3/auth/token"]}," webhook we sent. This will allow your server to ensure it’s only receiving requests coming from Tyro Health."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"setup","__idx":8},"children":["Setup"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To set up the webhook signing, please contact the customer support to apply for a secret token that will be used for signature signing. Once the secret key is generated, it will be delivered either via keybase (preferred) or secure email."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"validating-requests-from-tyro-health-online","__idx":9},"children":["Validating requests from Tyro Health Online"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Once your secret token is set by Tyro Health Online , every ",{"$$mdtype":"Tag","name":"highlight","attributes":{"backgroundcolour":"green"},"children":["POST"]},"  ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<base-url>/v3/auth/token"]}," request coming from Tyro Health Online will include two additional headers:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["X-Sender-Signature | A SHA-256 HMAC hash that's generated based on X-Sender-Timestamp value and JSON stringified payload."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["X-Sender-Timestamp | Date in ISO date string format. It represents the date the request was sent. Also, It will be used for HMAC hash calculation."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"...\nX-Sender-Signature=215d022a9e9c95fab7ca7c618d0d7b8d9e6dca1055d544b3d2421312a16a5651\nX-Sender-Timestamp=\"2021-01-13T04:23:50.659Z\"\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To verify the hmac signature, you will need to compute your own SHA-256 HMAC signature and compare it with the signature provided in the header. So the code will be something like this:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"js","header":{"controls":{"copy":{}}},"source":"const hmacSignature = Crypto.createHmac(\"sha256\", SECRET_TOKEN)\n                            .update(`${headers[\"X-Sender-Timestamp\"]}${JSON.stringify(payload)}`)\n                            .digest(\"hex\");\nreturn Crypto.timingSafeEqual(new Buffer.from(hmacSignature, \"utf-8\"), new Buffer.from(headers[\"X-Sender-Signature\"], \"utf-8\"));\n","lang":"js"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Implementation between different languages might be different. However, things to note above are:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The HMAC function has to use SHA256 method"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The base for computing the hash is comprised of the timestamp in the header and stringified payload in the request"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Try to use timingSafeEqual equivalent function to compare the HMAC result to avoid timing attack on large string comparison"]}]}]},"headings":[{"value":"Webhooks","id":"webhooks","depth":1},{"value":"Use cases","id":"use-cases","depth":2},{"value":"Steps to receive webhooks","id":"steps-to-receive-webhooks","depth":2},{"value":"Example","id":"example","depth":2},{"value":"Event handling","id":"event-handling","depth":2},{"value":"Retries","id":"retries","depth":3},{"value":"Sequencing & ordering","id":"sequencing--ordering","depth":3},{"value":"Webhook signature (optional)","id":"webhook-signature-optional","depth":2},{"value":"Setup","id":"setup","depth":3},{"value":"Validating requests from Tyro Health Online","id":"validating-requests-from-tyro-health-online","depth":3}],"frontmatter":{"title":"Webhooks","seo":{"title":"Webhooks"}},"lastModified":"2024-03-27T23:49:44.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/developer-portal/wcq/webhooks","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}