Accept a payment
Redirect your customers to the Vayapay hosted payment page, so card data never reaches your systems. From test API key to confirmed payment in about 10 minutes.
With the hosted payment page, Vayapay shows the payment form and handles every redirect the payment needs, including 3-D Secure. Your customers enter their payment details on the hosted page, so you never store or process card data. This keeps your PCI DSS scope as small as possible.
In this guide you create an order, pay it on the hosted payment page in test mode, and confirm the result with a webhook and a status request. No money moves.
How it works
Before you begin
- A Vayapay test account.
- A server that can make HTTPS requests. The examples use cURL, Node.js 18+, Python 3 and PHP.
- For the webhook: a URL that's reachable from the internet. On your own machine, use a tunnelling tool to expose your local server.
Get your test API key
- Log in to the merchant portal at https://merchant.secure.vayapay.com.
- Create a project in test mode, or open an existing test project.
- Go to Settings > API Key and copy the key.
Store the key as an environment variable on your server, so it doesn't end up in your code:
export API_KEY="your-test-api-key"Keep your API key secret
The API key gives full access to your project. Only use it from your server. Never put it in a browser, mobile app or public repository.
The API uses HTTP Basic authentication: your API key is the username and the password is empty. Retrieve your project to check that the key works:
curl https://api.secure.vayapay.com/v1/merchants/self/projects/self/ \
--user "$API_KEY:"A 200 OK response with your project details means you're connected. A 401 Unauthorized response means the API key is wrong.
Create an order
When your customer checks out, your server creates an order. This example creates an order for € 9.95. The amount is in cents.
curl https://api.secure.vayapay.com/v1/orders/ \
--user "$API_KEY:" \
--header "Content-Type: application/json" \
--data '{
"currency": "EUR",
"amount": 995,
"merchant_order_id": "EXAMPLE001",
"description": "Example order",
"return_url": "https://www.example.com/order/EXAMPLE001",
"webhook_url": "https://www.example.com/webhook"
}'Replace the return_url and webhook_url with URLs of your own server. The API responds with the new order:
{
"id": "1c969951-f5f1-4290-ae41-6177961fb3cb",
"currency": "EUR",
"amount": 995,
"merchant_order_id": "EXAMPLE001",
"description": "Example order",
"return_url": "https://www.example.com/order/EXAMPLE001",
"webhook_url": "https://www.example.com/webhook",
"created": "2026-10-12T11:41:57.121017+00:00",
"modified": "2026-10-12T11:41:57.183822+00:00",
"expiration_period": "PT1H",
"order_url": "https://api.secure.vayapay.com/pay/1c969951-f5f1-4290-ae41-6177961fb3cb/",
"status": "new"
}Save the id with your order: you need it to look up the order later.
Only currency and amount are required. The amount is in the smallest currency unit: 995 is € 9.95. See Create an order in the API reference for all fields.
Redirect your customer
Redirect your customer to the order_url. For this test, open it in your browser.
The hosted payment page shows every payment method that's active in your project. Select one and complete the payment with test details from Test data. After the payment, the browser goes to your return_url.
Don't rely on the redirect alone
Your customer can close the browser before they're redirected, and anyone can open your return_url. Always check the order status from your server before you show a confirmation or deliver.
Handle the webhook
When the order status changes, Vayapay sends a POST request to your webhook_url:
{
"event": "status_changed",
"order_id": "1c969951-f5f1-4290-ae41-6177961fb3cb",
"project_id": "b5f39273-44e7-4385-8e08-44612ef3e117"
}The webhook deliberately doesn't contain the status. Retrieve the order from the API, update your order with its status, and respond with 200 OK within 4 seconds. Vayapay retries a failed webhook, so handle the same notification safely more than once.
See Confirm the payment for an example handler in Node.js and Python, and the full delivery rules.
Check the status
Retrieve the order when you receive the webhook, and when your customer lands on your return_url:
curl https://api.secure.vayapay.com/v1/orders/1c969951-f5f1-4290-ae41-6177961fb3cb/ \
--user "$API_KEY:"{
"id": "1c969951-f5f1-4290-ae41-6177961fb3cb",
"amount": 995,
"currency": "EUR",
"merchant_order_id": "EXAMPLE001",
"status": "completed",
"completed": "2026-10-12T11:43:12.402150+00:00",
"transactions": [
{
"id": "058cf70d-7a84-4957-941c-532c065cef72",
"payment_method": "credit-card",
"status": "completed"
}
]
}The response is shortened. Act on the order status:
| Status | What to do |
|---|---|
completed | The payment succeeded. Confirm the order and deliver. |
new, processing | Not final yet. Show a "payment pending" message and wait for the next webhook. |
cancelled, expired, error | No payment. Let your customer try again. |
Webhooks can be delayed or lost: also check orders that aren't final after a while. See Confirm the payment.
You've created, paid and confirmed your first test payment.
Test your integration
Before you go live, test the outcomes your checkout has to handle. Use the test cards and amounts in Test data:
- A successful payment: the order becomes
completedand you deliver. - A declined payment: the order becomes
errorand your customer can try again. - Your customer cancels on the hosted payment page: the order becomes
cancelled. - Your customer closes the browser before the redirect: the webhook still updates your order.
- Your webhook endpoint fails once: the retry updates your order.
Go live
- Make sure your live project is active, with the payment methods you need.
- Use the API key of your live project in production.
- Set the webhook URL of your live project, or send
webhook_urlwith every order. - Make a small real payment and refund it.
See the go-live checklist for everything to check.
Beyond the basics
Customize the payment page
Show only some payment methods, let your customer choose in your own checkout, and prefill customer details.
Mobile apps
Open the hosted payment page from your Android or iOS app.
Pre-authorize and capture
Reserve the amount now and charge it when you ship.
One-click and recurring payments
Store the card and charge it again later.
See Beyond the basics for everything you can add.