Processing Callback
After successfully generating a payment link and your customer completes (or cancels) their payment, Paysera will send a callback notification to your server. This callback is crucial for confirming payment status and updating your system accordingly.
What is a Callback?​
A callback (also known as a webhook or IPN - Instant Payment Notification) is an automated server-to-server notification from Paysera that informs your system about the payment outcome.
Never rely solely on the customer returning to your accept/cancel URL. Callbacks ensure you're always notified of payment status, even if:
- The customer closes their browser after payment
- Network issues prevent the redirect
- The customer navigates away from the payment page
How Callbacks Work​
The Callback Flow​
- Customer completes payment on Paysera's payment page
- Paysera sends HTTP POST request to your
callbackurl - Your server receives the callback data
- Your server verifies the signature for security
- Your server updates the order status in your database
- Your server responds with "OK" to acknowledge receipt
- Paysera redirects the customer back to your website
Callback URL Requirements​
Your callback URL must meet these requirements:
- Accessible from the internet - Paysera's servers must be able to reach it
- HTTPS recommended - For production environments
- HTTP allowed - For testing/development
- No authentication required - Must be publicly accessible
- Fast response - Should respond within 30 seconds
- Returns "OK" - Must output exactly "OK" for successful processing
Your callback endpoint must be accessible without any authentication. Paysera cannot handle basic auth, session cookies, or other authentication mechanisms.
Callback Parameters​
View All Parameters
| Parameter | Description |
|---|---|
data | Encoded parameters from Paysera system. Same data coding algorithm is used as in generating a request for macro payments (steps 1-3). |
ss1 | Sign of data parameter, without a private-public key scheme. Sign algorithm: ss1 = md5(data + password) |
ss2 | Sign of data parameter, using RSA private-public key scheme with SHA-1 hashing function. You can download the public Paysera key, which should be used to verify the signature here. |
Payment Status Values​
| Status | Meaning | Explanation |
|---|---|---|
0 | Payment has not been executed | The payment hasn't been executed yet |
1 | Payment successful | The payment has been successfully completed |
2 | Payment order accepted, but not yet executed | The order was accepted, but the payment hasn't been executed yet |
3 | Additional information | Sent whenever the bank provides additional information about the payer |
4 | Payment executed, but confirmation about received funds in bank won't be sent | Sent when you are using the beneficiary parameters to receive the funds to a different bank, check if you have received the funds before completing the order |
Implementing Callback Handler​
Basic PHP Example
<?php
// callback.php - Your callback endpoint
require_once('WebToPay.php');
function isPaymentValid(array $order, array $response): bool
{
if (array_key_exists('payamount', $response) === false) {
if ($order['amount'] !== $response['amount'] || $order['currency'] !== $response['currency']) {
throw new Exception('Wrong payment amount');
}
} else {
if ($order['amount'] !== $response['payamount'] || $order['currency'] !== $response['paycurrency']) {
throw new Exception('Wrong payment amount');
}
}
return true;
}
try {
$response = WebToPay::validateAndParseData(
$_REQUEST,
{{YOUR_PROJECT_ID}},
{{YOUR_PROJECT_PASSWORD}}
);
// Statuses 1 (payment successful) and 3 (additional information) should be
// treated as a successful notification that the order can be approved.
if ($response['status'] === '1' || $response['status'] === '3') {
//@ToDo: Validate payment amount and currency, example provided in isPaymentValid method.
//@ToDo: Validate order status by $response['orderid']. If it is not already approved, approve it.
echo 'OK';
} else {
throw new Exception('Payment was not successful');
}
} catch (Exception $exception) {
echo get_class($exception) . ':' . $exception->getMessage();
}
For non-PHP integrations, see Custom Integration - the callback signature uses the same algorithm as the request signing described there.
Testing Callbacks​
Local Development with ngrok
For local development:
# Install ngrok
brew install ngrok # macOS
# Start your local server
php -S localhost:8000
# In another terminal, start ngrok
ngrok http 8000
# Use the ngrok URL as your callback URL
# Example: https://abc123.ngrok.io/callback.php
Manual Testing
Manually trigger a callback:
curl "http://localhost:8000/callback.php?projectid=123&orderid=TEST001&amount=1000¤cy=EUR&status=1&test=1&sign=YOUR_SIGNATURE"
Common Issues​
Callback Not Received
Possible causes:
- Callback URL not accessible from internet
- Firewall blocking Paysera's servers
- URL requires authentication
- Server returned error instead of "OK"
Solutions:
- Test URL:
curl https://yoursite.com/callback.php - Check server logs for incoming requests
- Ensure URL is publicly accessible without auth
- Verify response is exactly "OK"
Invalid Signature Error
Debug signature calculation:
error_log('Received signature: ' . $receivedSign);
error_log('Calculated signature: ' . $calculatedSign);
error_log('Sign string: ' . $signString);
error_log('Using password: ' . substr($projectPassword, 0, 3) . '...');
Duplicate Callbacks
Implement idempotency checking:
if (isCallbackProcessed($orderId, $receivedSign)) {
echo 'OK'; // Already processed
exit;
}
processPayment($orderId, $status);
saveProcessedCallback($orderId, $receivedSign);
echo 'OK';
Callback Timeout
Process asynchronously if needed:
// Queue for processing
queuePaymentProcessing($data);
// Respond immediately
echo 'OK';
exit;
Next Steps​
- Explore Complete Examples - More code samples
- Learn about Error Handling - Handle errors
- Check FAQ - Common questions