Easypay uses webhooks (also called notifications) to inform your application about events that happen in your Easypay account. This is a server-to-server service that sends near real-time notifications about payment status changes.
Webhooks are POST API calls (JSON encoded) that let your application know an event has happened. They enable your system to react automatically to payment events without constantly polling the API.
Webhooks are particularly useful for asynchronous events like:
- When a customer pays a Multibanco reference
- A frequent payment succeeds/fails
- A subscription payment succeeds/fails
- A checkout single sale payment succeeds/fails
- Authorization is granted or declined
- Capture is completed
With webhooks, your system can automate custom actions in response to the transitions that happen in a payment flow.
Easypay supports 3 notification types:
A notification informing about all state transitions of some payment resource.
Use Case: Comprehensive monitoring of all payment events
Payload Example:
{
"id": "5eca7446-14e9-47bb-aabb-5ee237159b8b",
"key": "dcf9ab3fd95ca3d5607853f36d46f161c8715858",
"type": "capture",
"status": "success",
"messages": ["Your request was successfully captured"],
"date": "2022-08-10 14:56:54"
}A notification informing about some payment transitioning to authorization status. Available for single and frequent payments.
Use Case: Specific monitoring of authorization events
Payload Example:
{
"id": "1bbc14c3-8ca8-492c-887d-1ca86400e4fa",
"value": 1,
"currency": "EUR",
"key": "the merchant key",
"expiration_time": "2022-01-01 10:20",
"customer": {
"id": "22ea3cc9-424b-489a-91b7-8955f643dc93",
"name": "Customer Example",
"email": "customer@example.com",
"phone": "911234567",
"phone_indicative": "+351"
},
"method": "mb",
"account": {
"id": "4c67e74b-a256-4e0a-965d-97bf5d01bd50"
},
"authorisation": {
"id": "4c67e74b-a256-4e0a-965d-97bf5d01bd50"
}
}A notification informing about some payment transitioning to capture status. Available for single and frequent payments.
Use Case: Specific monitoring of successful payment captures
Payload Example:
{
"id": "87615356-0a88-42bd-8abb-aab3e90128de",
"value": "40",
"currency": "EUR",
"key": "the merchant key",
"expiration_time": "2023-08-07 20:00",
"method": "MBW",
"customer": {
"id": "2eb64a7f-90a7-4dc6-959b-1d9aba44910c",
"phone": "910410419"
},
"account": {
"id": "0b8de6e7-89c8-4d76-93e8-019bc058f27d"
},
"transaction": {
"id": "eb23923b-3529-4b71-b54e-1e707a8d55c4",
"key": "transaction_key_of_this_capture",
"type": "capture",
"date": "2022-08-10T12:45:50Z",
"values": {
"requested": "40",
"paid": "40",
"fixed_fee": "0",
"variable_fee": "0",
"tax": "0",
"transfer": "0"
}
}
}Note: If you subscribe to both Generic and Authorisation notifications, you will receive two notifications for the same event with different message contracts.

- Easypay sends notification to your configured endpoint
- Your system receives notification and extracts the payment ID
- Your system queries Easypay API to verify the notification (recommended for security)
- Your system processes the payment according to the API response
- Log in to Easypay backoffice
- Navigate to
Developers > Configuration API 2.0 - Select the payment account you want to receive notifications
- Select
Notifications - Configure your endpoints:
- Generic - URL: For generic notifications
- Authorisation - URL: For authorisation notifications
- Payment - URL: For capture/transaction notifications
Your webhook endpoint must:
- Accept POST requests
- Accept JSON payloads
- Respond with HTTP 200 status code
- Process requests within 20 seconds
- Be accessible over HTTPS (recommended)
const express = require('express');
const axios = require('axios');
const app = express();
app.use(express.json());
app.post('/webhooks/easypay/generic', async (req, res) => {
const notification = req.body;
// 1. Acknowledge receipt immediately
res.status(200).send('OK');
// 2. Verify the notification by querying the API
try {
const response = await axios.get(
`https://api.prod.easypay.pt/2.0/single/${notification.id}`,
{
headers: {
'AccountId': process.env.EASYPAY_ACCOUNT_ID,
'ApiKey': process.env.EASYPAY_API_KEY
}
}
);
// 3. Process the verified payment
if (response.data.status === 'success') {
await processSuccessfulPayment(response.data);
} else {
await handleFailedPayment(response.data);
}
} catch (error) {
console.error('Error verifying notification:', error);
// Implement retry logic or alert system
}
});
async function processSuccessfulPayment(payment) {
// Your business logic here
console.log('Processing successful payment:', payment.id);
// Update database, send confirmation email, etc.
}
async function handleFailedPayment(payment) {
// Your error handling logic
console.log('Handling failed payment:', payment.id);
}
app.listen(3000);The id and key fields in generic notifications change according to payment type and operation:
| Payment Type | id | key |
|---|---|---|
| Single Authorisation | Single payment ID | key from create request |
| Single Capture | Single payment ID | transaction_key from capture request |
| Single Sale | Single payment ID | transaction_key from capture object in create request |
| Frequent Create | Frequent payment ID | key from create request |
| Frequent Authorization | Frequent payment ID | transaction_key from authorization request |
| Frequent Capture | Capture operation ID | transaction_key from capture request |
| Refund | Refund ID | transaction_key from refund request |
| Void | Void ID | transaction_key from void request |
| Subscription Create | Subscription ID | key from create request |
| Subscription Capture | Subscription ID | transaction_key from capture object |
| Chargeback Single | Single ID | transaction_key from create request |
| Chargeback Frequent | Capture operation ID | transaction_key from capture request |
| Out Payment | Out payment ID | key from create request |
- Always Verify Notifications: Query the Easypay API to confirm webhook authenticity
- Use HTTPS: Ensure your webhook endpoint uses HTTPS
- Validate Payload: Verify the payload structure before processing
- Idempotent Processing: Handle duplicate notifications gracefully
- IP Whitelisting: Optionally restrict access to Easypay's IP ranges
- Log Everything: Keep detailed logs for troubleshooting
- Monitor Failures: Alert on webhook processing failures
# 1. Start your local server
npm start # or python app.py
# 2. Expose local server with ngrok
ngrok http 3000
# 3. Use the ngrok URL in your Easypay backoffice
# Example: https://abc123.ngrok.io/webhooks/easypay/genericCreate test payments and monitor webhook delivery:
# Create a test payment
curl -X POST 'https://api.test.easypay.pt/2.0/single' \
-H 'AccountId: 2b0f63e2-9fb5-4e52-aca0-b4bf0339bbe6' \
-H 'ApiKey: eae4aa59-8e5b-4ec2-887d-b02768481a92' \
-H 'Content-Type: application/json' \
-d '{
"type": "sale",
"value": 10.00,
"method": "cc"
}'You can monitor webhook delivery via the Easypay backoffice:
- Log in to Easypay backoffice
- Navigate to
Developers > Notifications API 2.0 - Select your payment account
- View webhook delivery status, retry attempts, and response codes
If your webhook endpoint is unreachable or returns an error, Easypay will:
- Retry the webhook multiple times
- Use exponential backoff between retries
- Eventually mark the webhook as failed
- Payment Types - Understand different payment workflows
- Authorizations & Captures - Learn about auth/capture events
- API Reference - Webhook payload schemas
- Error Handling - Handle webhook errors gracefully