Instant Payments API
Accept instant SEPA payments from your customers with zero chargebacks, no rolling reserves, and same-day settlement. This API lets you create checkout sessions and receive payment confirmations.
Overview
The Dapit Instant Payments API enables merchants to accept EUR payments via SEPA Instant Credit Transfer. Instead of credit cards, your customers pay directly from their bank account (Wise, Revolut, or any EUR-enabled bank). Payments settle in under 10 seconds and are irrevocable — no chargebacks.
Base URL:
https://www.maxafi.com/api/gateway/gateway.php
Payment Flow
The customer never leaves your website. When they choose "Pay with Instant Payments" at your checkout, your server talks to our API behind the scenes.
Option A — API Integration (recommended): Your developer embeds the payment flow directly into your existing checkout page. The customer never leaves your site. You control the look and feel.
Option B — Hosted Checkout: If you don't have a developer, we provide a hosted checkout page. You redirect the customer to our URL and we handle everything. They see your merchant name on a Dapit-branded page.
Authentication
All API requests require your merchant API key. Include it in the request header:
X-Gateway-Key: your_api_key_here
Your API key is provided during merchant onboarding. Keep it secret — it authenticates all requests to our API on your behalf.
Quick Start — Option A: API Integration
Your developer adds Instant Payments as a payment option on your existing checkout page. The customer never leaves your website.
Step 1: Customer selects "Pay with Instant Payments" on your checkout
Your checkout page already has credit card, ACH, etc. Add an "Instant Payments" button alongside them. When they click it, your server creates a session:
// YOUR SERVER — Create a session when customer chooses Instant Payments const response = await fetch('https://www.maxafi.com/api/gateway/gateway.php?action=create_session', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Gateway-Key': 'your_api_key_here' }, body: JSON.stringify({ amount: 49.99, currency: 'EUR', items: [ { name: 'Premium Game Credits', qty: 1, price: 49.99, total: 49.99 } ], callback_url: 'https://yoursite.com/webhooks/dapit' }) }); const session = await response.json(); // session.session_token → save this (you'll need it for polling) // Now call create_invoice to get the payment details...
Step 2: Get payment details and display on YOUR page
// YOUR SERVER — Get the IBAN, beneficiary, and reference number const invoice = await fetch('https://www.maxafi.com/api/gateway/gateway.php?action=create_invoice', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token: session.session_token }) }).then(r => r.json()); // Display these on YOUR checkout page: // invoice.beneficiary_name → "Longemalle Trustees OU" // invoice.iban → "LT913740020058585210" // invoice.reference_number → "DP-260330-XA6HSX" // invoice.amount → 49.99 // invoice.invoice_number → "INV-260330-04821" // // Tell the customer: // 1. Open your banking app (Wise, Revolut, etc.) // 2. Send €49.99 to beneficiary "Longemalle Trustees OU" // 3. IBAN: LT913740020058585210 // 4. Reference: DP-260330-XA6HSX // 5. Click "I've Sent the Payment" button on your page
Step 3: Customer clicks "I Paid" — start polling
// YOUR PAGE (JavaScript) — When customer clicks "I Paid" // First, tell our API the customer says they paid await fetch('https://www.maxafi.com/api/gateway/gateway.php?action=confirm_paid', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token: sessionToken }) }); // Then poll every 7 seconds until payment is confirmed const pollInterval = setInterval(async () => { const check = await fetch('https://www.maxafi.com/api/gateway/gateway.php?action=check_payment', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token: sessionToken }) }).then(r => r.json()); if (check.status === 'confirmed') { clearInterval(pollInterval); // 🎉 Full payment confirmed! showPaymentSuccess(check.total_paid, check.invoice_amount); } else if (check.status === 'partial') { clearInterval(pollInterval); // ⚡ Partial payment — show receipt + remaining balance showPartialPayment(check.total_paid, check.amount_remaining, check.payments); // When customer sends remaining: call confirm_paid again, restart polling } else if (check.status === 'overpaid') { clearInterval(pollInterval); // 💰 Overpayment — order confirmed, refund will be processed showOverpaid(check.total_paid, check.overpaid_amount, check.refund_net, check.refund_fee); } else if (check.status === 'timeout') { clearInterval(pollInterval); showPaymentRetry(); } // 'pending' — keep polling }, 7000);
Step 4: Receive webhook confirmation (your server)
// YOUR SERVER — Webhook endpoint receives POST when payment is confirmed // Fires for both exact and overpayments (not for partial — only when fully paid) app.post('/webhooks/dapit', (req, res) => { const { event, merchant_order_id, invoice_amount, amount_paid, overpaid_amount, refund_amount, refund_fee } = req.body; if (event === 'payment.confirmed') { // ✅ Payment confirmed! Update your order database. console.log(`Order ${merchant_order_id} paid: €${amount_paid} of €${invoice_amount}`); if (overpaid_amount > 0) { // Customer overpaid — refund of €(overpaid - fee) will be processed console.log(`Overpaid by €${overpaid_amount}. Refund: €${refund_amount} (fee: €${refund_fee})`); } // Mark order as paid, send confirmation email, trigger fulfillment } res.status(200).json({ received: true }); });
Quick Start — Option B: Hosted Checkout
If you don't have a developer or want the simplest possible integration, use our hosted checkout page. You just create a session and redirect — we handle the entire payment UI.
// YOUR SERVER — Create session and redirect customer to our hosted page const session = await fetch('https://www.maxafi.com/api/gateway/gateway.php?action=create_session', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Gateway-Key': 'your_api_key_here' }, body: JSON.stringify({ amount: 49.99, currency: 'EUR', items: [{ name: 'Premium Game Credits', qty: 1, price: 49.99, total: 49.99 }], callback_url: 'https://yoursite.com/webhooks/dapit' }) }).then(r => r.json()); // Redirect customer to our hosted checkout res.redirect('https://www.maxafi.com' + session.checkout_url); // Customer sees: your merchant name, invoice, IBAN, reference, "I Paid" button // When confirmed, we POST to your callback_url
Create Session
Creates a new checkout session. Returns a checkout URL to redirect your customer to.
Headers
| Name | Value |
|---|---|
| X-Gateway-Key | Your merchant API key REQUIRED |
| Content-Type | application/json |
Request Body
| Parameter | Type | Description |
|---|---|---|
| amount | number | Payment amount in EUR REQUIRED |
| currency | string | Currency code. Default: EUR OPTIONAL |
| items | array | Array of line items: [{name, qty, price, total}] OPTIONAL |
| order_id | string | Your own order/invoice number (e.g. ORD-12345). Returned in webhook so you can match to your system. OPTIONAL |
| customer_email | string | Customer's email address OPTIONAL |
| customer_name | string | Customer's name OPTIONAL |
| callback_url | string | URL we POST to when payment is confirmed OPTIONAL |
| expires_minutes | number | Session expiry in minutes. Default: 60 OPTIONAL |
Response
{
"success": true,
"session_id": 42,
"session_token": "a1b2c3d4e5f6...",
"checkout_url": "/checkout/pay.html?session=a1b2c3d4e5f6...",
"expires_at": "2026-03-30 23:30:00",
"amount": 49.99,
"currency": "EUR",
"merchant_order_id": "ORD-12345"
}
Create Invoice
Generates the invoice, reference number, and returns the IBAN + beneficiary details. Call this after create_session to get the payment information to display on your checkout page. This is the key endpoint for Option A integration.
Request Body
| Parameter | Type | Description |
|---|---|---|
| token | string | The session_token from create_session REQUIRED |
Response
{
"success": true,
"reference_number": "DP-260330-XA6HSX",
"invoice_number": "INV-260330-04821",
"amount": 49.99,
"currency": "EUR",
"iban": "LT913740020058585210",
"beneficiary_name": "Longemalle Trustees OU",
"account_name": "Dapit Financial Infrastructure",
"bank_name": "ConnectPay"
}
Confirm Paid
Call this when the customer clicks "I've Sent the Payment" on your page. This tells our system to start checking ConnectPay for the incoming transfer.
Request Body
| Parameter | Type | Description |
|---|---|---|
| token | string | The session_token REQUIRED |
Response
{
"success": true,
"status": "polling",
"reference": "DP-260330-XA6HSX",
"message": "Payment verification started. We are checking for your transfer."
}
Check Payment (Polling)
Poll this endpoint every 5-7 seconds after calling confirm_paid. It checks ConnectPay for incoming transfers matching your reference number. Handles exact payments, partial payments, and overpayments automatically.
Request Body
| Parameter | Type | Description |
|---|---|---|
| token | string | The session_token REQUIRED |
Response — Full Payment
{
"success": true,
"status": "confirmed",
"paid_at": "2026-03-31 10:05:12",
"invoice_amount": 7.00,
"total_paid": 7.00,
"payment_count": 1,
"payments": [{ "amount": 7.00, "debtor_name": "John Smith", "debtor_iban": "DE89370400440532013000" }],
"amount_match": true
}
Response — Partial Payment
If the customer sends less than the invoice amount, you get a partial status. Show the receipt and remaining balance, then let them send the rest using the same reference number. Call confirm_paid again to restart polling.
{
"success": true,
"status": "partial",
"invoice_amount": 7.00,
"total_paid": 3.00,
"amount_remaining": 4.00,
"payment_count": 1,
"payments": [{ "amount": 3.00, "debtor_name": "John Smith" }],
"message": "We received €3.00 of your €7.00 payment. Remaining balance: €4.00."
}
Response — Overpayment
If the customer sends more than the invoice amount, the order is confirmed but we flag the overpayment. A refund will be processed minus a €1.00 processing fee.
{
"success": true,
"status": "overpaid",
"paid_at": "2026-03-31 10:05:12",
"invoice_amount": 5.00,
"total_paid": 8.00,
"overpaid_amount": 3.00,
"refund_fee": 1.00,
"refund_net": 2.00,
"message": "Payment received! You overpaid by €3.00. A refund of €2.00 will be processed (€3.00 minus €1.00 processing fee)."
}
Response — Still Searching
{
"success": true,
"status": "pending",
"message": "Payment not yet detected. Checking again...",
"poll_count": 5,
"max_polls": 60
}
Response — Timeout
{
"success": true,
"status": "timeout",
"message": "Payment not detected after maximum attempts. Please contact support."
}
status: "partial", display the receipt and remaining balance to the customer. They send the remaining amount with the same reference number, click "I've Sent the Payment" again, and you call confirm_paid then resume polling. The system tracks all payments and confirms when the full amount is received.
Get Session
Retrieve details about a checkout session including its current status.
Parameters
| Parameter | Type | Description |
|---|---|---|
| token | string | The session_token from create_session REQUIRED |
Response
{
"success": true,
"session_id": 42,
"merchant_name": "Your Store Name",
"amount": 49.99,
"currency": "EUR",
"status": "confirmed",
"reference_number": "DP-260330-XA6HSX",
"invoice_number": "INV-260330-04821",
"paid_at": "2026-03-30 22:05:12"
}
Payment Status
Check the payment status for a specific reference number. Requires API key authentication.
Headers
| Name | Value |
|---|---|
| X-Gateway-Key | Your merchant API key REQUIRED |
Parameters
| Parameter | Type | Description |
|---|---|---|
| reference | string | The reference number (e.g. DP-260330-XA6HSX) REQUIRED* |
| session_token | string | Or use the session token instead REQUIRED* |
* Provide either reference OR session_token
Response
{
"success": true,
"reference_number": "DP-260330-XA6HSX",
"invoice_number": "INV-260330-04821",
"amount": 49.99,
"currency": "EUR",
"status": "confirmed",
"confirmed_at": "2026-03-30 22:05:12"
}
List Transactions
List all gateway transactions for your merchant account. Supports filtering by status and pagination.
Headers
| Name | Value |
|---|---|
| X-Gateway-Key | Your merchant API key REQUIRED |
Parameters
| Parameter | Type | Description |
|---|---|---|
| status | string | Filter: pending, polling, confirmed, failed, expired OPTIONAL |
| limit | number | Results per page (max 200). Default: 50 OPTIONAL |
| offset | number | Pagination offset. Default: 0 OPTIONAL |
Response
{
"success": true,
"transactions": [
{
"reference_number": "DP-260330-XA6HSX",
"amount": 49.99,
"status": "confirmed",
"confirmed_at": "2026-03-30 22:05:12"
}
],
"total": 1,
"limit": 50,
"offset": 0
}
Webhook: Payment Confirmed
When a payment is confirmed, we send a POST request to your registered callback_url with the payment details.
callback_url parameter) or contact us to set a default URL for all your sessions.
Webhook Payload
{
"event": "payment.confirmed",
"reference_number": "DP-260330-XA6HSX",
"invoice_number": "INV-260330-04821",
"merchant_order_id": "ORD-12345",
"invoice_amount": 7.00,
"amount_paid": 7.00,
"amount_remaining": 0,
"overpaid_amount": 0,
"refund_amount": 0,
"refund_fee": 0,
"currency": "EUR",
"paid_at": "2026-03-31 10:05:12",
"session_token": "a1b2c3d4e5f6...",
"customer_email": "john@example.com",
"customer_name": "John Smith"
}
invoice_amount is 5.00 and amount_paid is 8.00, the webhook will include overpaid_amount: 3.00, refund_fee: 1.00, and refund_amount: 2.00. The order is still confirmed — the refund is handled separately.
Expected Response
Return a 200 status code to acknowledge receipt. If we don't get a 200, we'll flag the notification as undelivered.
PHP Example
<?php $payload = json_decode(file_get_contents('php://input'), true); if ($payload['event'] === 'payment.confirmed') { $orderId = $payload['merchant_order_id']; // YOUR order number $ref = $payload['reference_number']; // Our reference (DP-XXXXXX-XXXXXX) $amount = $payload['amount']; $paidAt = $payload['paid_at']; $email = $payload['customer_email']; // Match to your order and mark as paid $db->query("UPDATE orders SET status = 'paid', paid_at = '$paidAt' WHERE order_id = '$orderId'"); // Send confirmation email to customer // Trigger fulfillment / shipping error_log("Order $orderId paid: €$amount (ref: $ref)"); } http_response_code(200); echo json_encode(['received' => true]);
Session & Transaction Statuses
| Status | Description |
|---|---|
pending | Session created, customer hasn't reached checkout yet |
invoiced | Customer is on the checkout page, invoice + reference generated |
polling | Customer clicked "I've Sent the Payment" — we're checking ConnectPay |
partial | Payment received but less than invoice amount — waiting for remaining balance |
confirmed | Full payment received and verified ✓ |
overpaid | Payment received but more than invoice amount — refund will be processed (minus €1 fee) |
failed | Payment not detected after maximum polling attempts |
expired | Session expired before payment was made |
Error Handling
All errors return a JSON object with success: false and an error message:
{
"success": false,
"error": "Missing API key"
}
| HTTP Code | Meaning |
|---|---|
400 | Bad request — missing or invalid parameters |
401 | Unauthorized — invalid or missing API key |
404 | Not found — session or transaction doesn't exist |
Testing & Environments
Every merchant account starts in staging mode. This lets you integrate and test the full payment flow using ConnectPay's staging environment before going live with real money.
Staging vs Production
| Feature | Staging | Production |
|---|---|---|
| ConnectPay API | api-stage.connectpay.com | api.connectpay.com |
| Real money | No — test transactions only | Yes — real EUR transfers |
| IBAN | Staging IBAN (provided during onboarding) | Production IBAN |
| API Key | Same key — environment is set on your merchant account | Same key |
| Webhook | Fires normally — test your endpoint | Fires normally |
staging. Once you've tested successfully, contact us and we'll flip your account to production. The create_session response includes an environment field so you always know which mode you're in.
Integration Checklist — Staging
Test Accounts for Staging
Use these pre-funded test IBANs to simulate payments in the staging environment. Send EUR from either account to the staging custodial IBAN with the reference number from your checkout session.
| Account Name | IBAN | BIC | Currency | Balance |
|---|---|---|---|---|
| Bank Has No Money | LT923740020074597273 |
CNPALT21XXX | EUR | €100.00 |
| Bank Has Money | LT223740020032524104 |
CNPALT21XXX | EUR | €10,000.00 |
Integration Checklist
- Call
create_sessionwith your API key and verify you get asession_token - Call
create_invoiceand verify you receive the IBAN, beneficiary name, and reference number - Display the payment details on your checkout page
- Send a small EUR payment (€1-5) from Wise/Revolut to the staging IBAN with the reference number
- Call
confirm_paidand then pollcheck_paymentevery 7 seconds - Verify
check_paymentreturnsstatus: "confirmed" - Verify your webhook endpoint receives the
payment.confirmedevent with yourmerchant_order_id - Call
payment_statusand verify it returnsconfirmed
Going Live
- Contact us to switch your account from staging to production
- No code changes needed — same API key, same endpoints, same flow
- Verify
create_sessionresponse shows"environment": "production" - Run one real test transaction (€1) to confirm end-to-end
- You're live!
Create Refund
Initiate a full or partial refund for a completed payment. A €1 processing fee is deducted automatically.
| Parameter | Type | Description |
|---|---|---|
| api_key | string required | Your merchant API key |
| reference | string required | Original payment reference number |
| amount | number required | Refund amount (must be ≤ original payment amount) |
| reason | string optional | Reason for refund |
Response:
{
"success": true,
"refund_id": 42,
"reference_number": "R7A3F2B1",
"amount": 25.00,
"processing_fee": 1.00,
"status": "pending"
}
Send Refund
Execute a pending refund via SEPA transfer to the customer's IBAN. Calls ConnectPay's outbound payment API.
| Parameter | Type | Description |
|---|---|---|
| api_key | string required | Your merchant API key |
| refund_id | integer required | Refund ID from create_refund |
| debtor_iban | string required | Customer's IBAN to send refund to |
| debtor_name | string required | Customer's name on the bank account |
List Refunds
Returns all refunds for the authenticated merchant. Optionally filter by reference or status.
Settlement Report
Get an aggregated settlement report for a date range — gross volume, refunds, fees, and net settlement amount with daily breakdown.
| Parameter | Type | Description |
|---|---|---|
| api_key | string required | Your merchant API key |
| date_from | string required | Start date (YYYY-MM-DD) |
| date_to | string required | End date (YYYY-MM-DD) |
Response includes: gross_volume, total_refunds, total_fees, net_settlement, daily_breakdown array, and transaction_count.
Dashboard
Returns merchant dashboard KPIs: today's volume, this month's volume, all-time volume, success rate, average transaction, 7-day trend, and recent transactions.
Recurring Billing — Overview
The recurring billing system sends periodic payment reminders to customers via SMS and/or email. Each cycle generates a new reference number and a link back to the merchant's checkout page. The customer must voluntarily initiate each payment — this is not a direct debit.
Base URL:
https://www.maxafi.com/api/recurring.php
Authentication: Same gateway merchant API key via X-Api-Key header or api_key parameter.
Create Schedule
| Parameter | Type | Description |
|---|---|---|
| action | string required | create_schedule |
| customer_name | string required | Customer's full name |
| customer_email | string | Email for payment link delivery |
| customer_phone | string | Phone with country code (e.g. +4712345678) for SMS |
| delivery_method | string | email, sms, or both (default: email) |
| frequency | string required | weekly, biweekly, bimonthly, monthly |
| amount | number required | Payment amount per cycle (before discount) |
| discount_percent | number | Recurring discount (e.g. 5 for 5% off) |
| currency | string | Currency code (default: EUR) |
| order_items | array | JSON array of cart items: [{"name":"...", "qty":1, "price":99}] |
| order_description | string | Description shown to customer |
| payment_url | string | Your checkout URL — customer is sent here each cycle |
| start_date | string | First billing date (YYYY-MM-DD, default: tomorrow) |
| total_cycles | integer | Max cycles (0 = unlimited) |
Example:
curl -X POST https://www.maxafi.com/api/recurring.php \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "create_schedule",
"customer_name": "John Smith",
"customer_email": "john@example.com",
"customer_phone": "+4712345678",
"delivery_method": "both",
"frequency": "monthly",
"amount": 99.00,
"discount_percent": 5,
"currency": "EUR",
"order_items": [{"name": "Premium Plan", "qty": 1, "price": 99}],
"payment_url": "https://merchant-site.com/pay"
}'
Response:
{
"success": true,
"schedule_id": 7,
"amount": 94.05,
"original_amount": 99.00,
"discount_percent": 5,
"frequency": "monthly",
"next_billing_date": "2026-04-03"
}
List Schedules
Returns all recurring schedules for the merchant. Optionally filter by status (active, paused, cancelled, completed).
Update Schedule
Update a schedule: pause, resume, cancel, change amount or frequency.
| Parameter | Type | Description |
|---|---|---|
| action | string | update_schedule |
| schedule_id | integer required | Schedule to update |
| status | string | active, paused, cancelled |
| amount | number | New amount per cycle |
| frequency | string | New frequency |
| next_billing_date | string | Override next billing date (YYYY-MM-DD) |
Recurring — Configuration
Configure Twilio (SMS) and Gmail SMTP (email) credentials for payment notifications. Stored securely in the database.
| Parameter | Type | Description |
|---|---|---|
| action | string | set_config |
| twilio_sid | string | Twilio Account SID |
| twilio_token | string | Twilio Auth Token |
| twilio_phone | string | Twilio phone number (platform default) |
| smtp_user | string | Gmail address for sending |
| smtp_pass | string | Gmail App Password |
| smtp_from_name | string | Sender display name (default: Dapit Payments) |
gateway_merchants record via the fields sms_phone, email_from, and email_from_name. If set, these override the platform defaults.