Webhooks
To obtain automatic transaction updates, or for notifications were the response is delayed, Tyro Health supports the following events for each Medicare transaction:
Use cases
Partners can use webhook event notifications to alert them:
-
That an invoice has been approved (
healthFundApprovedInvoice
-
That an invoice has been Paid (
healthFundPaidInvoice
-
That an invoice has been rejected (
healthFundRejectedInvoice
Patient Claims
As patient Claim is an exceptional case because the patient receives the benefit (as opposed to the provider in all our other funder payments).
Here's how to deal with the businessStatus for Patient Claims:
Use case : when the invoiceCompleted
webhook is fired the payment has been taken from the patient
-
If
businessStatus=completed
the claim has been approved. -
If
businessStatus=outstanding
the claim object needs further interrogation if you need you know more info on the claim status (see below). -
If
businessStatus=declined
the claim has beenrejected
.
Info on transaction.claims[].status:
-
pending
- the claim has been stored and forwarded and will be resubmitted later (e.g. when medicare is down) -
under-review
- the claim been put in a process for manual review (please note that we unfortunately don't get any further updates from Medicare) -
approved
- the claim is approved -
rejected
- the claim is rejected
Steps to receive webhooks
Use the webhooks attribute and provide:
POST/GET/PUT/DELETE
Example
medipassTransactionSDK.renderCreateTransaction({
...
webhooks: [
{
url: 'https://your-site.com/transactions/your-transactionId/approved',
event: 'healthFundApprovedInvoice',
method: 'POST',
headers: { sessionKey: 'your required header' }
},
{
url: 'https://your-site.com/transactions/your-transactionId/paid',
event: 'healthFundPaidInvoice',
method: 'POST',
headers: { sessionKey: 'your required header' }
},
{
url: 'https://your-site.com/transactions/your-transactionId/rejected',
event: 'healthFundRejectedInvoice',
method: 'POST',
headers: { sessionKey: 'your required header' }
}
]
...
})
or
medipassTransactionSDK.renderCreateTransaction({
...
webhooks: [
{
url: 'https://your-site.com/transactions/your-transactionId/event-triggers',
event: 'healthFundApprovedInvoice,healthFundPaidInvoice,healthFundRejectedInvoice',
method: 'POST',
headers: { sessionKey: 'your required header' }
}
]
...
})
Event handling
Retries
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.
Sequencing & ordering
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.
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
Webhook signature (optional)
To enhance the webhook security further, we support signing the payload with SHA-256 hmac signature for each of the <base-url>/v3/auth/token
webhook we sent. This will allow your server to ensure it’s only receiving requests coming from Tyro Health.
Setup
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.
Validating requests from Tyro Health Online
Once your secret token is set by Tyro Health Online , every <base-url>/v3/auth/token
request coming from Tyro Health Online will include two additional headers:
- X-Sender-Signature | A SHA-256 HMAC hash that's generated based on X-Sender-Timestamp value and JSON stringified payload.
- 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.
...
X-Sender-Signature=215d022a9e9c95fab7ca7c618d0d7b8d9e6dca1055d544b3d2421312a16a5651
X-Sender-Timestamp="2021-01-13T04:23:50.659Z"
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:
const hmacSignature = Crypto.createHmac("sha256", SECRET_TOKEN)
.update(`${headers["X-Sender-Timestamp"]}${JSON.stringify(payload)}`)
.digest("hex");
return Crypto.timingSafeEqual(new Buffer.from(hmacSignature, "utf-8"), new Buffer.from(headers["X-Sender-Signature"], "utf-8"));
Implementation between different languages might be different. However, things to note above are:
- The HMAC function has to use SHA256 method
- The base for computing the hash is comprised of the timestamp in the header and stringified payload in the request
- Try to use timingSafeEqual equivalent function to compare the HMAC result to avoid timing attack on large string comparison