Dapit Card Gateway API Merchant Documentation

Card Gateway API

Accept Visa, Mastercard, JCB, and Amex payments with 2D and 3D Secure support. Process card payments through a single API, with automatic fraud screening, velocity controls, and real-time settlement.

Overview

The Dapit Card Gateway provides a server-to-server API for processing credit and debit card payments. Send card details directly from your backend and receive real-time authorization results.

PCI Compliance: Because your server handles raw card numbers, you must be PCI DSS compliant (at minimum SAQ D). If you prefer not to handle card data, contact us about our hosted checkout page.
1
Collect Card
Your checkout collects card details
2
Create Charge
POST to our API with card + amount
3
3DS (if required)
Redirect cardholder if 3DS triggered
4
Confirmation
Receive result via response or webhook

Authentication

All requests require your API key sent as a header:

X-Gateway-Key: your_api_key_here

You can also pass it as a query parameter api_key, but the header method is preferred. Your API key is available in the MaxaFi dashboard under the merchant's Instant Payments → Settings tab.

Keep your API key secret. Never expose it in client-side code, public repositories, or URLs that end users can see. All API calls must be made from your server.

Base URL

# Production
https://www.maxafi.com/api/gateway/card_gateway.php

# All endpoints use the ?action= parameter
https://www.maxafi.com/api/gateway/card_gateway.php?action=create_charge

Create Charge

Process a card payment. The gateway automatically determines whether 3D Secure is required based on the card issuer and risk assessment.

POST /card_gateway.php?action=create_charge

Request Body (JSON)

ParameterTypeRequiredDescription
amountnumberRequiredCharge amount (e.g. 49.99). Max 2 decimal places.
currencystringRequiredISO 4217 code: USD, EUR, GBP, etc.
card_numberstringRequiredFull card number (no spaces or dashes)
card_expirystringRequiredExpiration date: MM/YYYY or MM/YY
card_cvvstringRequired3 or 4 digit security code
cardholder_namestringRequiredFull name as on card
emailstringRequiredCardholder email address
phonestringRequiredCardholder phone number
billing_addressstringRequiredBilling street address
billing_citystringRequiredBilling city
billing_statestringRequiredBilling state/province
billing_zipstringRequiredBilling postal/zip code
billing_countrystringRequiredISO 3166-1 alpha-2 code: US, GB, etc.
order_idstringOptionalYour internal order/reference ID
descriptionstringOptionalDescription shown in reports
customer_idstringOptionalYour internal customer identifier
return_urlstringOptionalURL to redirect after 3DS verification

Example Request

// cURL
curl -X POST "https://www.maxafi.com/api/gateway/card_gateway.php?action=create_charge" \
  -H "Content-Type: application/json" \
  -H "X-Gateway-Key: your_api_key" \
  -d '{
    "amount": 49.99,
    "currency": "USD",
    "card_number": "4111111111111111",
    "card_expiry": "12/2027",
    "card_cvv": "123",
    "cardholder_name": "John Doe",
    "email": "john@example.com",
    "phone": "12125551234",
    "billing_address": "123 Main St",
    "billing_city": "New York",
    "billing_state": "NY",
    "billing_zip": "10001",
    "billing_country": "US",
    "order_id": "ORD-20260402-001",
    "description": "Widget purchase"
  }'

Success Response (2D — No 3DS)

{
  "success": true,
  "charge_id": "ch_a1b2c3d4e5f6a7b8c9d0e1f2",
  "status": "succeeded",
  "amount": 49.99,
  "currency": "USD",
  "fees": {
    "mdr": 1.45,
    "transaction": 0.30,
    "total": 1.75
  },
  "net_amount": 48.24,
  "card_brand": "Visa",
  "card_last4": "1111",
  "merchant_order_id": "ORD-20260402-001"
}

3DS Required Response

{
  "success": true,
  "charge_id": "ch_a1b2c3d4e5f6a7b8c9d0e1f2",
  "status": "pending_3ds",
  "requires_action": true,
  "action_type": "3ds_redirect",
  "redirect_url": "https://3ds.provider.com/verify?token=abc123",
  "message": "Redirect the cardholder to redirect_url for 3D Secure verification.",
  "amount": 49.99,
  "currency": "USD"
}

Declined Response

{
  "success": true,
  "charge_id": "ch_a1b2c3d4e5f6a7b8c9d0e1f2",
  "status": "failed",
  "error_message": "Insufficient funds",
  "amount": 49.99,
  "currency": "USD"
}

3D Secure Flow

When the issuing bank requires 3D Secure verification, the create_charge response will include requires_action: true and a redirect_url.

1
Create Charge
You POST card details
2
Receive redirect_url
status = pending_3ds
3
Redirect Customer
Send them to the URL
4
Webhook Callback
We POST result to your callback_url

Handling 3DS in Your Code

// After calling create_charge
if (response.requires_action && response.redirect_url) {
    // Store charge_id in your session/database
    saveChargeId(response.charge_id);

    // Redirect the cardholder to 3DS verification
    window.location.href = response.redirect_url;
}

// Your webhook endpoint receives the result:
{
  "event": "charge.succeeded",
  "charge_id": "ch_a1b2c3d4e5f6a7b8c9d0e1f2",
  "status": "succeeded",
  "amount": 49.99,
  "confirmed_at": "2026-04-02T14:30:00Z"
}
Important: After redirecting for 3DS, do NOT assume the payment succeeded. Always verify by checking the webhook callback or polling get_charge with the charge_id.

Get Charge

Retrieve the current status and details of a charge.

GET /card_gateway.php?action=get_charge&charge_id=ch_xxx
ParameterTypeRequiredDescription
charge_idstringRequired*The charge ID returned from create_charge
order_idstringRequired*Your merchant order ID (alternative to charge_id)

* Provide either charge_id or order_id.

Response

{
  "success": true,
  "charge_id": "ch_a1b2c3d4e5f6a7b8c9d0e1f2",
  "status": "succeeded",
  "amount": 49.99,
  "currency": "USD",
  "fees": { "mdr": 1.45, "transaction": 0.30, "total": 1.75 },
  "net_amount": 48.24,
  "card_brand": "Visa",
  "card_last4": "1111",
  "merchant_order_id": "ORD-20260402-001",
  "description": "Widget purchase",
  "created_at": "2026-04-02 14:25:00",
  "confirmed_at": "2026-04-02 14:25:02",
  "refunded_amount": 0
}

Create Refund

Refund a succeeded charge. Supports full and partial refunds.

POST /card_gateway.php?action=create_refund
ParameterTypeRequiredDescription
charge_idstringRequiredThe charge to refund
amountnumberOptionalPartial refund amount. Omit for full refund.
reasonstringOptionalReason for refund

Response

{
  "success": true,
  "refund_id": "rf_x1y2z3a4b5c6d7e8f9g0h1i2",
  "charge_id": "ch_a1b2c3d4e5f6a7b8c9d0e1f2",
  "status": "succeeded",
  "amount": 49.99,
  "refund_fee": 0.00,
  "net_refund": 49.99
}

List Charges

Retrieve a paginated list of your charges with optional filters.

GET /card_gateway.php?action=list_charges
ParameterTypeRequiredDescription
statusstringOptionalFilter: succeeded, failed, pending_3ds, refunded
fromstringOptionalStart date: YYYY-MM-DD
tostringOptionalEnd date: YYYY-MM-DD
limitintegerOptionalResults per page (default 50, max 200)
offsetintegerOptionalPagination offset

Charge Statuses

StatusDescriptionIs Final?
succeededPayment authorized and captured successfullyYes
failedPayment declined by issuer or gatewayYes
pending_3dsAwaiting 3D Secure cardholder verificationNo — will become succeeded or failed
processingPayment submitted, awaiting confirmationNo — will become succeeded or failed
refundedFully refundedYes
partially_refundedPartially refunded (check refunded_amount)Yes
disputedCardholder filed a chargebackNo — pending resolution

Webhooks

Set your callback_url in the MaxaFi dashboard (Instant Payments → Settings). We POST JSON to this URL when:

Webhook Payload

{
  "event": "charge.succeeded",
  "charge_id": "ch_a1b2c3d4e5f6a7b8c9d0e1f2",
  "merchant_order_id": "ORD-20260402-001",
  "amount": 49.99,
  "currency": "USD",
  "status": "succeeded",
  "card_brand": "Visa",
  "card_last4": "1111",
  "confirmed_at": "2026-04-02T14:30:00Z",
  "timestamp": "2026-04-02T14:30:01+00:00"
}

Webhook Events

EventDescription
charge.succeededPayment was authorized and captured
charge.failedPayment was declined after 3DS or async processing
refund.succeededRefund processed successfully
refund.failedRefund attempt failed
Respond with 200 OK. Your webhook endpoint must return HTTP 200 to acknowledge receipt. We do not retry failed deliveries currently.

Error Codes

When a request fails, the response includes success: false and an error field:

{
  "success": false,
  "error": "Amount exceeds single transaction limit of USD 5,000.00"
}
ErrorCause
Missing API keyNo X-Gateway-Key header or api_key parameter
Invalid or inactive API keyKey doesn't match or merchant is disabled
Amount must be positiveAmount is zero or negative
Amount below minimumBelow the merchant's configured min_txn_amount
Amount exceeds maximumAbove the merchant's configured max_txn_amount
Daily volume limit exceededMerchant's daily processing cap reached
Monthly volume limit exceededMerchant's monthly processing cap reached
Velocity limit: card per daySame card used too many times today
Velocity limit: card per hourSame card used too many times this hour
Velocity limit: card amount per daySame card exceeded daily $ limit
Velocity limit: IP per dayToo many transactions from same IP
Velocity limit: email per dayToo many transactions from same email
Transaction declinedCard issuer declined the transaction
Insufficient fundsCard has insufficient balance
Invalid card numberCard number failed validation
Expired cardCard expiration date has passed

Test Cards

Use these card numbers in test mode. The first card below is the gateway provider's official test card with specific CVV and expiry.

Card NumberBrandCVVExpiryResult
4444 3333 2222 1111Visa66606/2026Approved (2D) — Primary Test Card
4111 1111 1111 1111VisaAny 3 digitsAny future dateApproved (2D)
5500 0000 0000 0004MastercardAny 3 digitsAny future dateApproved (2D)
4000 0000 0000 0002VisaAny 3 digitsAny future dateDeclined
4000 0000 0000 3220VisaAny 3 digitsAny future date3DS Required
3530 1113 3330 0000JCBAny 3 digitsAny future dateApproved
3782 822463 10005AmexAny 4 digitsAny future dateApproved
Test mode: Test transactions are not sent to the card network. Switch to production mode in MaxaFi when you're ready to go live.

Code Examples

PHP

// PHP — Create a charge
$ch = curl_init('https://www.maxafi.com/api/gateway/card_gateway.php?action=create_charge');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-Gateway-Key: your_api_key'
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'amount' => 49.99,
        'currency' => 'USD',
        'card_number' => '4111111111111111',
        'card_expiry' => '12/2027',
        'card_cvv' => '123',
        'cardholder_name' => 'John Doe',
        'email' => 'john@example.com',
        'phone' => '12125551234',
        'billing_address' => '123 Main St',
        'billing_city' => 'New York',
        'billing_state' => 'NY',
        'billing_zip' => '10001',
        'billing_country' => 'US',
        'order_id' => 'ORD-001',
    ]),
    CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);

if ($result['success'] && $result['status'] === 'succeeded') {
    // Payment approved!
    echo "Charge " . $result['charge_id'] . " approved.";
} elseif ($result['requires_action']) {
    // Redirect for 3DS
    header('Location: ' . $result['redirect_url']);
} else {
    // Declined
    echo "Error: " . $result['error_message'];
}

Node.js

// Node.js — Create a charge
const response = await fetch(
  'https://www.maxafi.com/api/gateway/card_gateway.php?action=create_charge',
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Gateway-Key': 'your_api_key',
    },
    body: JSON.stringify({
      amount: 49.99,
      currency: 'USD',
      card_number: '4111111111111111',
      card_expiry: '12/2027',
      card_cvv: '123',
      cardholder_name: 'John Doe',
      email: 'john@example.com',
      phone: '12125551234',
      billing_address: '123 Main St',
      billing_city: 'New York',
      billing_state: 'NY',
      billing_zip: '10001',
      billing_country: 'US',
      order_id: 'ORD-001',
    }),
  }
);
const data = await response.json();

if (data.status === 'succeeded') {
  console.log('Approved:', data.charge_id);
} else if (data.requires_action) {
  console.log('Redirect to:', data.redirect_url);
} else {
  console.log('Declined:', data.error_message);
}

Python

# Python — Create a charge
import requests

result = requests.post(
    'https://www.maxafi.com/api/gateway/card_gateway.php?action=create_charge',
    headers={
        'Content-Type': 'application/json',
        'X-Gateway-Key': 'your_api_key',
    },
    json={
        'amount': 49.99,
        'currency': 'USD',
        'card_number': '4111111111111111',
        'card_expiry': '12/2027',
        'card_cvv': '123',
        'cardholder_name': 'John Doe',
        'email': 'john@example.com',
        'phone': '12125551234',
        'billing_address': '123 Main St',
        'billing_city': 'New York',
        'billing_state': 'NY',
        'billing_zip': '10001',
        'billing_country': 'US',
    }
).json()

if result['status'] == 'succeeded':
    print(f"Approved: {result['charge_id']}")
elif result.get('requires_action'):
    print(f"3DS redirect: {result['redirect_url']}")
else:
    print(f"Declined: {result.get('error_message')}")