To obtain automatic transaction updates, or for notifications were the response is delayed, we support the following events for each transaction:
For Virtual Terminal transactions:
Webhook | Description |
---|---|
invoiceCreated | Invoked when a transaction is successfully created in Medipass. |
invoiceCompleted | Invoked when a transaction is successfully completed, and nothing left is owing to the provider. |
invoiceCancelled | Invoked when the transaction is cancelled by the provider, or rejected by the patient/cardholder. |
For Funder transactions:
Webhook | Description |
---|---|
invoiceCompleted | Invoked when a transaction is successfully completed, and nothing left is owing to the provider. |
invoiceCancelled | Invoked when the transaction is cancelled by the provider, or rejected by the patient/cardholder. |
invoiceBalancePaid | Notice on successful patient payment. When the balance goes to zero, this webhook will fire, regardless of how it was paid for. |
healthFundApprovedInvoice | For health fund delayed decision transactions where the claim was approved. |
healthFundRejectedInvoice | for health fund delayed decision transactions where the claim was rejected. |
healthFundPaidInvoice | for health fund delayed decision transactions where the claim was paid. |
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.
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. For example, you might have an invoiceCreated event arrive after invoiceCompleted event if payment is immediately processed.
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 GET Invoice API to determine to current status.
To enhance the webhook security further, we support signing the payload with SHA-256 hmac signature for each of the POST webhook we sent. This will allow your server to ensure it's only receiving requests coming from Medipass.
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.
Once your secret token is set by Medipass, every POST requests coming from Medipass will include two additional headers:
...
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:
To set a webhook, use the webhooks
attribute and provide:
medipassTransactionSDK.renderCreateTransaction({
...
webhooks: [
{
url: 'https://your-site.com/transactions/your-transactionId/success',
event: 'healthFundApprovedInvoice',
method: 'POST',
headers: { sessionKey: 'Hello world' }
},
{
url: 'https://your-site.com/transactions/your-transactionId/failure',
event: 'healthFundRejectedInvoice',
method: 'POST',
headers: { sessionKey: 'Hello world' }
},
{
url: 'https://your-site.com/transactions/your-transactionId/paid',
event: 'healthFundPaidInvoice',
method: 'POST',
headers: { sessionKey: 'Hello world' }
}
]
...
})
or
medipassTransactionSDK.renderCreateTransaction({
...
webhooks: [
{
url: 'https://your-site.com/transactions/your-transactionId/event-triggers',
event: 'healthFundApprovedInvoice,healthFundRejectedInvoice,healthFundPaidInvoice',
method: 'POST',
headers: { sessionKey: 'Hello world' }
}
]
...
})