Webhook notifications

When a transaction is updated, we send a digitally signed POST request to the specified callback URL with a type of PAYMENT_STATUS_CHANGE, REFUND_STATUS_CHANGE, PAYOUT_STATUS_CHANGE, or PAYER_DETAILS to designate the type of update. Each type relates to a different structure depending on the transaction type. Make sure you follow the right structure for payment status updates, payer account details, refund status updates or payout status updates.

🚧

Be aware

  1. Callbacks will timeout after 1 minute. If Vyne is unable to establish a connection, or does not receive a response after 1 minute, the request will timeout.
  2. In order to receive webhook notifications from from Vyne's servers, you must whitelist the relevant IP addresses listed here.
  3. In order to protect the transfer of consumer data the payer account details webhook call requires the receiving server to have a valid, un-expired, and un-revoked SSL certificate. Learn more about the requirements here.
  4. Webhook notifications can only be sent to a secure (HTTPS) page.

Setting callback URLs

21002100

You can specify different callback URLs for each type of webhook (single payments, payer account details, refunds, and payouts) for your Merchant or Partner account.

  1. Sign in to the Merchant portal or Partner portal.
  2. Click your account name in the right of the navigation bar, and click the Settings option in the account menu.
  3. Enter the URL to receive webhook notifications in the relevant field, then click the Update button below the field.

👍

Try it out

You can use a single URL for all webhook types by simply inputting the same URL.

Verifying webhook integrity

Every webhook notification sent by Vyne is digitally signed using public key cryptography (also known as asymmetric cryptography) and will allow the merchant verify the origin and the integrity of the message.

Example response

curl -X 'POST' 'https://payvyne.com/webhook' 
-H 'content-length: 320' 
-H 'content-type: application/json' 
-H 'x-signature: AaXWxwZvNvx1gwOhnnUF3vzRkKduOsRXiVWEAUmLnDcjua6xRFn/mNE3Mve2hiiHbtES9E2urNn8jwUeVvVspnoRyzWkbgvpY1I5g0J5dtHNi6l/vTIWsMOO2xdkqGaW/v8h82ul4rbMZaE/qbnF/dPXrB0YNunhL0EK3owHQQX93Xas9L5H2EJIl8nFfiMlvo3pisPfZtR8uoyS0oUMWM1HGoWI4NlOphlcp2hqNFS5S1grC8pAMMBom71VgKvtFGmS9NOCvBKgOnQMIJlsOUZt+2o5ilAjaMxPv+tQusZ4LTnI3oSLUCrFy5xv4FeXwhuVF+xBianvdN5VKUkW/q30NyCn5QkkEqVYWov+SVhUVJGPhZH9RvIh1qCEKcCezlBI3zLg4Hh6731royto/cfST59/88XuTsNdKTuXQVuFLiTyT3+TQvQdv6EW0yH3/96/AxvZujPSBUUoi2JOqNbj6ohfeuEomdwfnfhnvLLNZtjv9wwGRER7jqaqYLWnMIwhinxaDvntQ66qJT2H9m2DzAgp5LVRObA4ygNG5PtaV25tGUIeazf/qDaSffZXJZ1L0WrV03GMUjRIN4eViTAHju+P/QaV9rDyM20MaR2VniedMyFKzPUoBr5Cu94vXfuRgdtHusrjhzvjRs/sJ3D9lgU4TrDdqViG/6s7TXE=' 
-H 'x-signature-keyid: 557ffe73-e658-4972-8c32-97ef5ffc06e1' 
-d $'{"paymentId":"97b9b0fdb3cd444d","status":"NO_CONSENT","timestamp":1654591074817,"amount":"1.00","currency":"GBP","description":"Example","paymentType":"ONE_OFF","destinationAccount":"GBP2","createdAt":"2022-06-07T08:37:54.817","updatedAt":"2022-06-07T08:37:54.817","refundedAmount":"0.00","type":"PAYMENT_STATUS_CHANGE"}'
ParameterDescription
x-signatureA signature generated by Vyne which will allow the merchant verify the origin and the integrity of the message. The signature is base64 encoded string with a length of 684 characters
x-signature-keyIdKey ID of the public key which can be used to verify the signature. It’s a 36 character string displayed in five groups separated by hyphens in the following format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.

There are two keys which are mathematically linked: one private and one public key.

  • The private key is used by the Vyne webhook to generate a signature.
  • The public key is available publicly and can be used to confirm if the signature is valid.
RoleResponsibility
Signature generation (by Vyne)A hash is calculated from the notification body which is then encrypted with the private key.
Signature verification (by the merchant)The signature is decrypted with the public key and it must match with the computed hash of the notification body. If the outcomes don't match, the notification body has either been tampered with or the signature was created with a private key that doesn't correspond to the public key presented by the signer.

Merchants are responsible for validating the origin and the integrity of every message. In order to validate the message, you'll need:

  1. The body of the notification - make sure that you have access to the raw message payload, any modification or formatting of the payload will fail validation of the signature.
  2. KeyId from the x-signature-keyId response header, and the corresponding public key.
  3. Signature from the x-signature response header
  4. Signing algorithm SHA256withRSA

📘

Helpful to know

The latest API keys can be found at the relevant base URL + /api/keys/.

The /api/keys/ endpoint can return multiple public keys in JWKS format, therefore the key with ID corresponding to the x-signature-keyId response header should be used. After the right key is identified, an RSA public key should be constructed from the JWK

In order to check the integrity of the message, the signature (x-signature header) must be decrypted with the public key and the decrypted value must match the hash of the body. Most languages provide support to do this without an external library.

For example, Java/Kotlin uses the Signature class.

val signature: Signature = Signature.getInstance("SHA256withRSA")
signature.initVerify(publicKey)
signature.update(notificationBody.encodeToByteArray())
 
if (signature.verify(Base64.getDecoder().decode(signatureHeader))) {
    //Signature check passed
} else {
    //Signature check failed
}

🚧

Be aware

  1. The existing structure and fields won’t be modified or removed, however Vyne might extend the structure with new fields, so keep this in mind when configuring your parser.
  2. We recommend verifying the integrity of messages using the above outlined methods every time. If the signature check fails, it could be for one of two reasons:
  • The wrong public key was used to check the signature. Make sure that the key used corresponds with the one in x-signature-keyId response header
  • The message was tampered with and should not be trusted or wasn’t sent by Vyne.