Skip to main content

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.

Why Callbacks are Critical

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​

  1. Customer completes payment on Paysera's payment page
  2. Paysera sends HTTP POST request to your callbackurl
  3. Your server receives the callback data
  4. Your server verifies the signature for security
  5. Your server updates the order status in your database
  6. Your server responds with "OK" to acknowledge receipt
  7. 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
Important

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
ParameterDescription
dataEncoded parameters from Paysera system. Same data coding algorithm is used as in generating a request for macro payments (steps 1-3).
ss1Sign of data parameter, without a private-public key scheme. Sign algorithm: ss1 = md5(data + password)
ss2Sign 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​

StatusMeaningExplanation
0Payment has not been executedThe payment hasn't been executed yet
1Payment successfulThe payment has been successfully completed
2Payment order accepted, but not yet executedThe order was accepted, but the payment hasn't been executed yet
3Additional informationSent whenever the bank provides additional information about the payer
4Payment executed, but confirmation about received funds in bank won't be sentSent 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();
}
Other languages

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&currency=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​