Skip to main content

Overview

Webhooks allow Payviox to send real-time notifications to your server when payment events occur. When a payment is processed, Payviox sends an HTTP POST request to your configured webhook URL with the payment details.
Webhooks are essential for keeping your application synchronized with payment statuses. Configure your webhook URL in the Payviox Dashboard under Settings > Webhooks.

Webhook Configuration

Setting Up Your Webhook URL

1

Configure Your Endpoint

Create an endpoint on your server to receive POST requests (e.g., https://yourdomain.com/api/webhook)
2

Add URL to Dashboard

Go to your Payviox Dashboard and navigate to Settings > Webhooks
3

Enter Your Webhook URL

Paste your endpoint URL in the webhook URL field
4

Save Your Webhook Token

Copy your webhook token - you’ll need it to verify webhook signatures
Always verify webhook signatures to ensure requests are coming from Payviox and not from malicious actors.

Webhook Payload Structure

Payviox sends webhooks with the following structure:
{
  "amount": 10000,
  "currency": "USD",
  "metadata": {
    "integration_session_id": "sess_abc123xyz"
  },
  "type": "succeeded",
  "provider": "stripe",
  "order_id": "order_123456",
  "items": [
    {
      "name": "Premium Subscription",
      "quantity": 1,
      "price": 10000
    }
  ],
  "payment_method": "card"
}

Payload Fields

amount
integer
required
The payment amount in the smallest currency unit (e.g., cents for USD)
currency
string
required
Three-letter ISO currency code (e.g., USD, EUR, GBP)
metadata
object
required
Custom metadata associated with the payment session
type
string
required
The payment status. Possible values:
  • succeeded: Payment completed successfully
  • processing: Payment is being processed
  • canceled: Payment was canceled
  • requires_payment_method: Additional payment method required
  • requires_confirmation: Payment requires confirmation
  • requires_action: Additional action required from customer
provider
string
required
The payment provider used (e.g., stripe, paypal, crypto)
order_id
string
required
Your unique order identifier
items
array
required
Array of items purchased
payment_method
string
Specific payment method used (e.g., card, bank_transfer)

Webhook Headers

Every webhook request includes these headers:
HeaderDescription
Content-TypeAlways application/json
SignatureHMAC SHA256 signature for verification

Signature Verification

Critical Security Step: Always verify the webhook signature before processing the payload. This ensures the request is legitimate and from Payviox.
The Signature header contains an HMAC SHA256 hash of the request body, signed with your webhook token. Here’s how to verify it:

Verification Algorithm

  1. Get the raw request body (JSON string)
  2. Compute HMAC SHA256 hash using your webhook token as the secret key
  3. Compare the computed signature with the Signature header
  4. Only process the webhook if signatures match

Implementation Examples

<?php

function verifyWebhookSignature($payload, $receivedSignature, $webhookToken) {
    // Compute the expected signature
    $computedSignature = hash_hmac('sha256', $payload, $webhookToken);
    
    // Use hash_equals to prevent timing attacks
    return hash_equals($computedSignature, $receivedSignature);
}

// Example usage in a Laravel controller
public function handleWebhook(Request $request) {
    // Get the raw payload
    $payload = $request->getContent();
    
    // Get the signature from headers
    $receivedSignature = $request->header('Signature');
    
    // Your webhook token from the dashboard
    $webhookToken = env('PAYVIOX_WEBHOOK_TOKEN');
    
    // Verify the signature
    if (!verifyWebhookSignature($payload, $receivedSignature, $webhookToken)) {
        // Invalid signature - reject the request
        return response()->json(['error' => 'Invalid signature'], 401);
    }
    
    // Parse the verified payload
    $data = json_decode($payload, true);
    
    // Process the webhook based on type
    switch ($data['type']) {
        case 'succeeded':
            // Payment succeeded - fulfill the order
            $this->fulfillOrder($data['order_id'], $data);
            break;
            
        case 'processing':
            // Payment is processing - update order status
            $this->updateOrderStatus($data['order_id'], 'processing');
            break;
            
        case 'canceled':
            // Payment was canceled - handle cancellation
            $this->cancelOrder($data['order_id']);
            break;
            
        case 'requires_action':
            // Customer action required - notify customer
            $this->notifyCustomerActionRequired($data['order_id']);
            break;
    }
    
    // Return 200 OK to acknowledge receipt
    return response()->json(['status' => 'success'], 200);
}

private function fulfillOrder($orderId, $webhookData) {
    // Your order fulfillment logic
    $order = Order::where('order_id', $orderId)->first();
    
    if ($order) {
        $order->status = 'completed';
        $order->payment_provider = $webhookData['provider'];
        $order->payment_amount = $webhookData['amount'];
        $order->session_id = $webhookData['metadata']['integration_session_id'];
        $order->save();
        
        // Send confirmation email, provision services, etc.
    }
}

Retry Logic

Payviox implements an automatic retry mechanism for failed webhook deliveries:
1

First Attempt

Instant delivery (0 seconds)
2

Second Attempt

30 seconds after first failure
3

Third Attempt

5 minutes after second failure
4

Fourth Attempt

30 minutes after third failure
After 4 failed attempts, the webhook will be marked as failed. You can manually retry failed webhooks from the Payviox Dashboard.

Success Criteria

A webhook is considered successfully delivered when your endpoint:
  • Returns HTTP status code 200
  • Responds within 30 seconds

Troubleshooting

Common Issues

Possible causes:
  • Using the wrong webhook token
  • Parsing/modifying the request body before verification
  • Incorrect HMAC algorithm (must be SHA256)
Solution: Always verify against the raw request body, before any parsing or modifications.
Possible causes:
  • Incorrect webhook URL in dashboard
  • Firewall blocking Payviox IP addresses
  • Server not responding within 30 seconds
Solution: Check your webhook URL configuration and server logs.
Possible causes:
  • Not implementing idempotency checks
  • Slow response times causing retries
Solution: Implement idempotency using session_id and order_id, and respond quickly with 200 OK.
Possible causes:
  • Processing taking too long before responding
  • Database locks or slow queries
Solution: Return 200 OK immediately and process webhooks asynchronously in a queue.

Security Checklist

Need Help?

If you’re having trouble with webhook integration:
Include your webhook attempt IDs from the dashboard when contacting support for faster resolution.