Vivamo will send webhooks at a number of stages of live payments, disbursements, and for number of key events for background processes.
Vivamo webhooks can provide authentication in two ways:
Custom headers may be provided by you that are sent with every webhook. For instance, a pre-shared key etc.
These headers should be provided to Vivamo during onboarding, and are setup when the webhooks are first registered in the following structure:
"headers": [
{"key": "SomeHeader", "value": "itsasecret"},
{"key": "SomeOtherHeader", "value": "1234"}
]
An HMAC authentication header signature
is passed with every webhook event, which is the body of the request signed with a pre-shared secret key.
For example:
// Webhook Body:
{
amount: "9.99",
status: "success",
transactionType: "payment",
externalCustomerId: "user_001",
paymentIntentId: "671f4e90c0811b1056da1653",
externalPaymentIntentId: "payment_intent_569"
}
// 'signature' header:
signature: "970fa31a9ab24a20b63d50d5a3009bae3fea00e1ad369e450f20846c6c14048dcbec37993f1c34cdacc2ff60a410b62e3488284c5520efcdb6965d47c888ea21"
Sample code that compares the hash:
const body = {...}
const secret = "...";
const hash = crypto
.createHmac("sha512", secret)
.update(JSON.stringify(body))
.digest("hex");
console.log(hash);
// output: 970fa31a9ab24a20b63d50d5a3009bae3fea00e1ad369e450f20846c6c14048dcbec37993f1c34cdacc2ff60a410b62e3488284c5520efcdb6965d47c888ea21
When a webhook is delivered to your server, a status 200 response should be return to ensure duplicate webhooks are not sent. Retry attempts will be made up to 5 times, with a backoff calculated as retry attempt * 1 minute.
Webhooks for payment results will be sent for all payment types in a common structure and format.
// Success
{
"amount": "15.50",
"status": "success",
"transactionType": "payment",
"externalCustomerId": "abc123",
"externalPaymentIntentId": "42cd8fa2-69da-4813-a312-eb061f9e535d"
}
// Failed
{
"amount": "15.50",
"status": "failed",
"subStatus": "declined",
"transactionType": "payment",
"externalCustomerId": "abc123",
"externalPaymentIntentId": "42cd8fa2-69da-4813-a312-eb061f9e535d"
}
A disbursement will get created in a pending state. When the funds are ready to send, the “Approve disbursement intent” endpoint can be called to either allow, or deny the continuation of the disbursement, which will then change the result and trigger the webhooks below.
{
"amount": "10",
"status": "pending-validation",
"transactionType": "disbursement",
"externalCustomerId": "user_001",
"externalDisbursementId": "disbursement_intent_134",
"externalDisbursementIntentId": "disbursement_intent_134",
"disbursementId": "670d1db475a0bd418fa57dcb",
"disbursementIntentId": "670d1da94cc9e76c80bfceea"
}
// Success
{
"amount": "15.50",
"status": "success",
"transactionType": "disbursement",
"externalCustomerId": "abc123",
"externalDisbursementId": "42cd8fa2-69da-4813-a312-eb061f9e535d"
}
// Failed
{
"amount": "15.50",
"status": "failed",
"subStatus": "error",
"transactionType": "disbursement",
"externalCustomerId": "abc123",
"externalDisbursementId": "42cd8fa2-69da-4813-a312-eb061f9e535d"
}