Shopify Integration
Configure webhooks to receive real-time notifications when payments are completed or transactions change status.
What are Webhooks?
Webhooks are HTTP callbacks that notify your application when payment events occur. Instead of continuously polling for status updates, U.Cash sends POST requests to your specified URL when:
- A payment is completed
- A transaction is confirmed
- A payment fails
- A transfer or conversion completes
Configuration
To configure webhooks in your U.Cash admin panel:
- Navigate to Settings → Webhook
- Enter your Webhook URL (e.g.,
https://yoursite.com/webhook) - Optionally set a Webhook Secret Key for signature verification
- Save your settings
URL Requirements
- Must be publicly accessible (not localhost)
- Should use HTTPS for security
- Must respond with HTTP 200 OK to acknowledge receipt
- Recommended timeout: 30 seconds
Security & Verification
To verify webhook authenticity, U.Cash can sign webhook payloads using a secret key.
Setting Up Webhook Secret
- In the admin panel, enter a secret key in the Webhook Secret Key field
- Store this key securely on your server
- Use it to verify incoming webhook signatures
Signature Verification
Each webhook request includes an X-Webhook-Signature header containing an HMAC-SHA256 hash:
signature = hmac_sha256(webhook_secret, payload_body)
Example verification in PHP:
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'];
$expectedSignature = hash_hmac('sha256', $payload, $webhookSecret);
if (hash_equals($signature, $expectedSignature)) {
// Webhook is verified
}
Webhook Events
Webhooks are sent for the following events:
| Event | Description |
|---|---|
payment_completed |
Payment successfully completed and confirmed |
payment_failed |
Payment failed or expired |
transfer_completed |
Funds transferred to configured wallet |
conversion_completed |
Currency conversion completed |
underpayment |
Payment received but amount was insufficient |
Webhook Payload Structure
{
"event": "payment_completed",
"timestamp": "2026-05-28T12:34:56Z",
"data": {
"transaction_id": "TX123456789",
"order_id": "ORD123",
"amount": "100.00",
"currency": "USD",
"crypto_amount": "0.0025",
"crypto_currency": "BTC",
"status": "completed",
"confirmations": 3
}
}
Testing Webhooks
To test webhooks during development:
- Use tools like webhook.site for testing
- Use ngrok or similar to expose localhost to the internet
- Check the admin panel for webhook delivery logs
- Enable testnet mode to test without real transactions
Troubleshooting
If webhooks aren't being delivered:
- Verify your URL is accessible from the internet
- Check your server logs for incoming requests
- Ensure your endpoint returns HTTP 200 OK
- Confirm webhook URL is saved correctly in settings
- Check if any firewall is blocking U.Cash servers
Best Practices
- Always verify signatures to ensure requests are from U.Cash
- Return quickly - Process webhooks asynchronously if needed
- Handle retries - U.Cash may retry failed webhook deliveries
- Use idempotency keys to prevent duplicate processing
- Log all webhooks for debugging and audit purposes
- Monitor failures and set up alerts for webhook delivery issues
Code Examples
PHP Webhook Handler
<?php
// webhook.php
$webhookSecret = 'your_secret_key';
// Get raw POST data
$payload = file_get_contents('php://input');
$data = json_decode($payload, true);
// Verify signature
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256', $payload, $webhookSecret);
if (!hash_equals($signature, $expected)) {
http_response_code(403);
exit('Invalid signature');
}
// Handle event
switch ($data['event'] ?? '') {
case 'payment_completed':
$transactionId = $data['data']['transaction_id'];
// Update your database, fulfill order, etc.
break;
case 'payment_failed':
// Handle failed payment
break;
}
// Acknowledge receipt
http_response_code(200);
echo 'OK';
?>
Node.js Webhook Handler
const express = require('express');
const crypto = require('crypto');
const app = express();
const webhookSecret = 'your_secret_key';
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
const signature = req.headers['x-webhook-signature'];
const expected = crypto.createHmac('sha256', webhookSecret)
.update(req.body)
.digest('hex');
if (signature !== expected) {
return res.status(403).send('Invalid signature');
}
const data = JSON.parse(req.body);
// Handle event
if (data.event === 'payment_completed') {
// Process payment
}
res.send('OK');
});
app.listen(3000);