Dapit Instant Payments Merchant Setup Guide

Merchant Setup Guide

This guide walks you through connecting your website to the Dapit Instant Payments platform, testing in the staging environment, and going live with real EUR payments.

Estimated time: A developer can complete the full integration in 1–2 hours. If you're using our Hosted Checkout (no coding), you can be testing in 10 minutes.

Prerequisites

Before you begin, make sure you have:

Security: Your API key authenticates every request. Never put it in client-side JavaScript, HTML, or mobile app code. All API calls go server → Dapit API → your server.

Step 1 — Verify Your API Key

1
Make a test API call

Open a terminal and run this curl command (replace YOUR_API_KEY with your actual key):

curl -X POST "https://www.maxafi.com/api/gateway/gateway.php?action=create_session" \
  -H "Content-Type: application/json" \
  -H "X-Gateway-Key: YOUR_API_KEY" \
  -d '{
    "amount": 1.00,
    "currency": "EUR",
    "items": [{"name": "Test Item", "qty": 1, "price": 1.00, "total": 1.00}]
  }'

Expected response:

{
  "success": true,
  "session_id": 1,
  "session_token": "a1b2c3d4e5f6...",
  "checkout_url": "/checkout/pay.html?session=a1b2c3d4...",
  "environment": "stage"
}
✓ If you see "success": true and "environment": "stage", your API key is working and you're connected to the staging environment. Save the session_token — you'll use it in the next steps.
✗ If you get "error": "Missing API key" or a 401 error, double-check your API key. Contact your ISO admin if the key was revoked or expired.

Step 2 — Choose Your Integration Method

2
Pick Option A or Option B
Option A: API IntegrationOption B: Hosted Checkout
Developer needed?YesNo
Customer experienceStays on your websiteRedirected to Dapit-branded page
BrandingFully your own designDapit page with your merchant name
Setup time1–2 hours10 minutes
Best forCustom checkout, full controlQuick start, no-code merchants

Option B — Hosted Checkout (no code)

If you don't have a developer, you can skip Steps 3–5 entirely. Just create a session from your server and redirect the customer:

// Create session (from your server), then redirect customer to:
https://www.maxafi.com/checkout/pay.html?session=SESSION_TOKEN

// We handle the entire payment UI.
// When confirmed, we POST to your callback_url.

Then skip ahead to Step 6 (Webhook).

Option A — API Integration

Continue to Step 3 below. You'll build the payment flow into your existing checkout page.

Step 3 — Create a Checkout Session

3
Your server creates a session and gets payment details

When a customer clicks "Pay with Instant Payments" on your checkout page, your server makes two API calls:

Call 1: Create Session

// POST to create_session — creates the payment session
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'
  },
  body: JSON.stringify({
    amount: 49.99,
    currency: 'EUR',
    order_id: 'ORD-12345',  // YOUR order number — returned in webhook
    customer_email: 'customer@example.com',
    customer_name: 'John Smith',
    callback_url: 'https://yoursite.com/webhooks/dapit',
    items: [
      { name: 'Premium Plan', qty: 1, price: 49.99, total: 49.99 }
    ]
  })
}).then(r => r.json());

// Save session.session_token — you need it for all subsequent calls

Call 2: Create Invoice

This generates the reference number and returns the IBAN + beneficiary details:

// POST to create_invoice — generates reference number + payment instructions
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());

// invoice.beneficiary_name → "Longemalle Trustees OU"
// invoice.iban             → "LT913740020058585210"
// invoice.bank_name        → "ConnectPay"
// invoice.reference_number → "DP-260406-XA6HSX"
// invoice.amount           → 49.99

Send these values back to your frontend to display on the checkout page.

Step 4 — Display Payment Instructions

4
Show the customer how to pay

On your checkout page, display the payment details from Step 3. The customer needs to see:

FieldExample ValueWhat to tell the customer
Beneficiary NameLongemalle Trustees OU"Send payment to this name"
IBANLT913740020058585210"Use this IBAN in your banking app"
Reference NumberDP-260406-XA6HSX"Enter this EXACTLY as the payment reference"
Amount€49.99"Send this exact amount"
BankConnectPayOptional — helps customer identify the bank
Important: The reference number is how we match the payment to the order. If the customer doesn't include it (or types it wrong), the payment won't be detected automatically. Make the reference number prominent and easy to copy.

The customer then:

  1. Opens their banking app (Wise, Revolut, N26, or any EUR-enabled bank)
  2. Creates a new SEPA transfer to the beneficiary name and IBAN
  3. Enters the reference number in the "Reference" or "Message to recipient" field
  4. Sends the exact EUR amount
  5. Returns to your page and clicks "I've Sent the Payment"

Add a prominent "I've Sent the Payment" button on your page. When they click it, you move to Step 5.

Step 5 — Handle "I Paid" and Poll for Confirmation

5
Start payment verification and poll until confirmed

When the customer clicks "I've Sent the Payment", your page makes two types of calls:

5a. Tell our API the customer says they paid

// Call confirm_paid — tells our system to start checking ConnectPay
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 })
});

5b. Poll every 7 seconds until payment is found

// Poll check_payment every 7 seconds
const poll = 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(poll);
    // ✅ Payment confirmed! Show success page.

  } else if (check.status === 'partial') {
    clearInterval(poll);
    // ⚠ Customer sent less than the invoice amount.
    // Show: "We received €X. Remaining: €Y. Send the rest with the same reference."
    // When they send more: call confirm_paid again, restart polling.

  } else if (check.status === 'overpaid') {
    clearInterval(poll);
    // 💰 Customer sent too much. Order is confirmed.
    // Refund of (overpaid - €1 fee) will be processed automatically.

  } else if (check.status === 'timeout') {
    clearInterval(poll);
    // ⏰ Payment not found after ~7 minutes. Show retry or contact support.
  }
  // "pending" — keep polling, show a spinner
}, 7000);
How long does verification take? SEPA Instant transfers arrive in 5–20 seconds. The polling loop runs for up to ~7 minutes (60 polls × 7 seconds). In practice, most payments confirm within 30 seconds of the customer sending.

Step 6 — Receive Webhook Confirmation

6
Your server receives a POST when payment is confirmed

When a payment is confirmed, we send a POST request to the callback_url you provided when creating the session. This is your server-side confirmation — use it to update your order database.

// Your webhook endpoint receives this JSON:
{
  "event": "payment.confirmed",
  "merchant_order_id": "ORD-12345",   // YOUR order number
  "reference_number": "DP-260406-XA6HSX",
  "invoice_amount": 49.99,
  "amount_paid": 49.99,
  "currency": "EUR",
  "paid_at": "2026-04-06 14:32:10",
  "customer_email": "customer@example.com",
  "customer_name": "John Smith"
}

Return HTTP 200 to acknowledge receipt. If we don't get a 200, the notification is flagged as undelivered.

PHP Example

<?php
$payload = json_decode(file_get_contents('php://input'), true);

if ($payload['event'] === 'payment.confirmed') {
    $orderId = $payload['merchant_order_id'];
    $amount  = $payload['amount_paid'];

    // Mark order as paid in your database
    $db->query("UPDATE orders SET status='paid' WHERE order_id='$orderId'");

    // Send confirmation email, trigger shipping, etc.
}

http_response_code(200);
echo json_encode(['received' => true]);

Test Accounts for Staging

Use these pre-funded test IBANs to simulate payments in the staging environment. No real money is involved.

Account NameIBANBICCurrencyBalance
Bank Has No Money LT923740020074597273 CNPALT21XXX EUR €100.00
Bank Has Money LT223740020032524104 CNPALT21XXX EUR €10,000.00
Note: Test balances are shared across all staging merchants. Use small amounts (€1–€5) for testing. Balances are reset periodically.

Run a Test Payment

Follow this exact sequence to test the full payment flow end-to-end:

  1. Create a session — call create_session with amount 1.00 and your webhook URL
  2. Create an invoice — call create_invoice with the session token. Save the IBAN, beneficiary, and reference number.
  3. Send a test payment — from one of the test accounts above, send €1.00 to the staging custodial IBAN with the reference number as the payment reference
  4. Confirm paid — call confirm_paid with the session token
  5. Poll for confirmation — call check_payment every 7 seconds. Within 30 seconds, you should get status: "confirmed"
  6. Check your webhook — verify your endpoint received the payment.confirmed POST with your merchant_order_id
  7. Verify via API — call payment_status with the reference number to confirm it shows confirmed
✓ If all 7 steps work, your integration is complete and ready for production.

Integration Checklist

Confirm each of these before requesting production access:

Switch to Production

Once your staging integration tests pass:

  1. Contact your ISO admin — ask them to switch your merchant account from staging to production in MaxaFi
  2. No code changes needed — same API key, same endpoints, same flow. The only difference is payments use real EUR transfers.
  3. Verify the switch — call create_session and check that the response includes "environment": "production"
  4. Run one live test — create a €1.00 session and send a real €1 payment from your own bank account to confirm end-to-end
  5. You're live! — start accepting real payments from your customers
That's it. No card networks, no rolling reserves, no chargebacks. Payments settle instantly and are irrevocable. Welcome to instant payments.

Payment Statuses

StatusMeaningWhat to do
pendingSession created, waiting for customerShow checkout page
invoicedInvoice + reference generatedDisplay payment instructions
pollingChecking ConnectPay for the transferShow spinner, keep polling
partialReceived less than the invoice amountShow receipt + remaining balance
confirmedFull payment received ✓Show success, fulfill order
overpaidReceived more than invoice amountOrder confirmed, refund auto-processed
failedNot found after max polling attemptsShow retry / contact support
expiredSession timed out before paymentCreate a new session

Common Errors

ErrorCauseFix
Missing API key (401)No X-Gateway-Key headerAdd the header to every API call
Invalid API key (401)Key doesn't match any active merchantCheck for typos. Ask your admin for a new key if needed.
API key expired (401)Key has a set expiration dateGenerate a new key from the MaxaFi Info tab
Session not found (404)Invalid or expired session tokenCreate a new session. Tokens expire after 60 min by default.
Session expiredCustomer took too longCreate a new session and restart checkout
Amount must be positive (400)Amount is 0 or negativePass a positive number for the amount
timeout status on check_paymentPayment not detected after ~7 minCustomer may not have sent it, or used wrong reference. Let them retry.

Frequently Asked Questions

How fast do payments confirm?

SEPA Instant transfers arrive in 5–20 seconds. From the moment the customer sends the payment in their banking app, you'll typically see confirmed within 30 seconds of polling.

What if the customer doesn't include the reference number?

The payment won't be automatically matched. The session will eventually time out. The funds will still arrive in the custodial account — contact support to manually reconcile.

Can customers pay from any bank?

Yes — any bank that supports SEPA transfers to an IBAN. This includes Wise, Revolut, N26, traditional banks, and any EUR-enabled account worldwide. The customer doesn't need a European bank — they just need to be able to send EUR to an IBAN.

Are there chargebacks?

No. SEPA Credit Transfers are irrevocable once sent. There is no chargeback mechanism. This is the primary advantage over card payments.

What about refunds?

You can initiate refunds via the API (create_refund) or from the MaxaFi dashboard. Refunds are sent as outbound SEPA payments to the customer's IBAN. A €1 processing fee applies per refund. See the API Reference for details.

Do I need to change anything when switching from staging to production?

No. Same API key, same endpoints, same code. Your ISO admin flips a switch on your merchant account. The only visible change is that create_session will return "environment": "production" instead of "stage".

Where can I see my transactions and settlements?

Log in to MaxaFi, open your merchant account, and go to the Info tab → Instant Payments Gateway section. You'll see a full dashboard with transactions, refunds, and settlement reports.

I need help. Who do I contact?

Contact your ISO admin or reach out through the MaxaFi ticket system. For API issues, include your merchant name, the API endpoint you're calling, and the full error response.