Reward DNA Webhooks

Virtual Incentives supports webhooks to provide real-time notifications when key reward lifecycle events occur. These webhooks allow clients to stay up-to-date as rewards move through their lifecycle from order creation to email or SMS delivery to activation. Webhooks are managed within our VI Now client portal.

📘

Webhooks require approval prior to access. Please contact your Virtual Incentives Account Manager to discuss your use case.

Getting Started

To manage your webhooks:

  1. Log in to VI Now.
  2. Navigate to the Webhooks section.
  3. Use the management interface to:
    1. Register endpoints to receive events
    2. Subscribe to specific event types
    3. View delivery logs

👤 An Admin must enable the Webhooks page in VI Now before users in the organization can access it.

Creating and Managing Endpoints

  1. In the Webhooks section, click Add Endpoint.
  2. Provide your endpoint URL and optional description.
  3. Optionally add custom headers.
  4. A signing secret will be generated for validating event signatures.

Subscribing to Events

You can subscribe to any combination of the following event types. This consolidated list reflects the order lifecycle, reward status updates, and payout events as used throughout the VI platform:

Event TypeDescription
order.createdA new order was successfully created.
order.processingOrder is currently being processed.
order.processedOrder has completed processing.
order.pending_fundsOrder is awaiting client funding.
order.canceledAn order was canceled before fulfillment.
reward.activated.auto_activatedReward was automatically activated.
reward.activated.instant_issuePhysical Instant Issue Visa card was activated via API.
reward.activated.phoneReward was activated via phone.
reward.activated.webReward was activated online.
reward.cancel_feeFee charged for canceling a reward.
reward.cancel_reissue_feeFee charged for canceling and reissuing a reward.
reward.canceledReward was canceled after delivery.
reward.claimedA recipient reveals their reward details, confirming successful delivery.
reward.credit_appliedRefund issued for a canceled reward.
reward.data_redacted.gdprReward data redacted due to GDPR compliance.
reward.data_redacted.retention_policyReward data redacted per retention policy.
reward.delivery_failedDelivery attempt failed (e.g., email or SMS undeliverable).
reward.delivery_failed.blacklistedDelivery failed due to blacklisted recipient or domain.
reward.email.link_extendedReward link expiration date was extended.
reward.email.resentReward email was resent.
reward.email.viewedReward email was viewed.
reward.extend_link_feeFee charged for extending reward link expiration.
reward.sms_resentReward SMS message was resent.
reward.link_clickedReward link was clicked.
reward.blocked_recipient_signals_fraudReward blocked due to potential fraud detected.
reward.idv.failedRecipient failed identity verification.
reward.idv.passedRecipient passed identity verification.
reward.multifactor_authentication.failedMFA attempt failed.
reward.multifactor_authentication.resetReward flagged for MFA failure was reset.
reward.online_registration_completedRecipient completed online account registration.
reward.reissued_rewardA reward was reissued.
reward.reminder_sentReminder sent for unclaimed reward.
reward.sentReward was successfully sent.
reward.sent.fm_overridePreviously flagged reward was whitelisted and sent.
reward.card_shippedA physical card was shipped.
reward.shipped_via_courierReward shipped using a courier service.
reward.recipient_reissue_feeFee charged for reissuing reward to recipient.
reward.payout.succeededPayPal or Venmo payout was successfully delivered.
reward.payout.unclaimedPayPal or Venmo payout sent to unregistered recipient; awaiting claim.
reward.payout.heldPayPal or Venmo payout is under review and temporarily held.
reward.payout.deniedPayPal or Venmo payout was declined by the recipient.
reward.payout.blockedPayPal or Venmo payout was blocked due to account or compliance issues.
reward.payout.refundedPayPal or Venmo payout was refunded after being claimed.
reward.payout.returnedPayPal or Venmo payout was voided and funds returned. For Cash Payouts, this means the recipient-provided bank details were invalid; an email is sent for re-enter bank details.
reward.payout.failedPayPal, Venmo, or Cash Payout attempt failed.
reward.payout.canceledPayPal, Venmo, or Cash Payout was canceled prior to processing.
reward.payout.bank_account_linkedCash Payout recipient entered bank account details.
reward.payout.sentCash Payout sent to the recipient's bank account.

Viewing Logs

Navigate to the Logs tab within the Webhooks interface to:

  • View webhook deliveries and retries
  • Inspect request/response payloads
  • Diagnose failed or delayed notifications

⏱️ Webhooks are retried automatically using exponential backoff.

📦Payload

Each webhook contains a JSON body with the following structure:

Example Webhook Payloads

{
  "date": "06/17/2025 16:01:56",
  "event": "reward.canceled",
  "event_id": "339133515",
  "note": "",
  "recipient_id": "42498355",
  "user": "John Smith"
  }
  
{
  "date": "06/17/2025 16:01:58",
  "event": "reward.credit_applied",
  "event_id": "339128032",
  "note": "$10.00",
  "recipient_id": "42498355",
  "user": "John Smith"
}

Payload Fields

StatusTypeDescription
datestringThe date/time when the webhook event occurred
eventstringThe event type (e.g., order.processed)
event_idstringA unique identifier for this specific webhook event
notestringNote added during a manually initiated event, or credit amount for reward cancelation.
recipient_idstringVirtual Incentives unique identifier associated with the reward
userstringClient user associated with a manually initiated event such as a cancelation

🔐Webhook Signature Verification

Each webhook includes headers that allow you to verify the authenticity of the request using an HMAC-based signature.

Required Headers

HeaderDescription
svix-idUnique message ID
svix-timestampUNIX timestamp of when the webhook was sent
svix-signatureHMAC-SHA256 signature of the message payload

How to Verify the Signature

  1. Concatenate the three values: svix-id, svix-timestamp, and the raw request body with a period (.) as a separator:
to_sign = svix-id + "." + svix-timestamp + "." + raw_body
  1. Compute the HMAC SHA256 digest of to_sign using your secret key (provided to you by VI), and encode it as a Base64 string:
import hmac
import hashlib
import base64

secret = base64.b64decode("your-secret-here")
signature = base64.b64encode(
    hmac.new(secret, to_sign.encode(), hashlib.sha256).digest()
).decode()
  1. Compare this computed signature with the one in the svix-signature header. If they match, the webhook is authentic.
⚠️

Security Tip

Always check that svix-timestamp is recent (e.g., within 5 minutes) to protect against replay attacks.

Additional Resources

Verifying webhook payloads - If you prefer to use a library rather than implement the verification logic manually, this guide provides examples in multiple languages and frameworks:

IP Addresses for Whitelisting - Optionally whitelist IP addresses from which webhook events will be delivered. The only applicable IPs for Virtual Incentives are listed under "US".

🔄 Retry Behavior

If your server does not respond with a 2xx HTTP status code, we will retry the webhook several times with exponential backoff.

Ensure your endpoint can safely handle duplicate events.

✅ Security Best Practices

  • Respond quickly with a 200 OK after validating and logging the event.
  • Always validate the svix-signature.
  • Store the latest status for each uuid to maintain a full verification history.
  • Secure your endpoint with HTTPS
  • Limit IP access or implement token-based authentication where possible.
  • Log and monitor webhook traffic for anomalies.

© Copyright 2019. All other rights reserved.