Custom E-Commerce UPI Gateway Integration

Eliminate 2-3% aggregator fees on Indian e-commerce carts with custom PHP and Node.js direct UPI checkout, dynamic QR, and instant webhooks.

For independent e-commerce brands, custom PHP shops, and Indian dropshippers, high payment aggregator processing fees (typically 2% + 18% GST) drastically eat into profit margins. Furthermore, traditional payment gateways hold funds in rolling reserves or enforce T+2 to T+3 settlement cycles, restricting cash flow needed for immediate inventory procurement and courier COD remits.

With UPIGateway.dev, e-commerce stores can accept direct-to-bank UPI payments at 0% commission. Funds deposit immediately into the store owner's linked bank account (PhonePe, GPay, Paytm, or Bank QR), enabling same-day inventory fulfillment.

E-Commerce Checkout Flow Architecture

  1. Cart Review: Customer completes shipping details and proceeds to payment.
  2. Order Creation: Server calls /api/create-order passing total cart value, order reference, and customer contact details.
  3. Dynamic QR & Intent Modal: The checkout page renders an embedded QR code or redirects to the clean /pay/:token screen.
  4. Automated Bank Verification: As soon as the customer approves the payment, our engine validates bank records and dispatches a verified webhook POST.
  5. Inventory Deduction & Order Dispatch: Your e-commerce backend locks inventory, marks the order 'Processing', and dispatches tracking information.

PHP E-Commerce Checkout Example

Here is a lightweight, dependency-free PHP script to create an order and handle the secure verification callback in any custom cart:

<?php
// cart_checkout.php — Universal PHP Cart UPI Checkout
require_once 'config.php';

$cartTotal   = 1299.00; // Calculated from cart session
$orderNumber = 'CART_' . time();
$customerEmail = filter_var($_POST['email'] ?? '', FILTER_SANITIZE_EMAIL);

// Call UPIGateway.dev /api/create-order
$payload = [
    'user_token'   => UPIGATEWAY_TOKEN,
    'amount'       => $cartTotal,
    'order_id'     => $orderNumber,
    'redirect_url' => 'https://myeshop.com/checkout/success.php?order=' . $orderNumber,
    'remark1'      => 'Cart Order #' . $orderNumber,
    'remark2'      => $customerEmail
];

$ch = curl_init('https://upigateway.dev/api/create-order');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => json_encode($payload),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_TIMEOUT        => 15
]);

$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);

if (!empty($result['status']) && !empty($result['result']['payment_url'])) {
    // Redirect customer to the secure payment screen
    header('Location: ' . $result['result']['payment_url']);
    exit;
} else {
    die('Failed to initialize payment: ' . htmlspecialchars($result['message'] ?? 'Unknown error'));
}

Handling Webhooks & Preventing Double Fulfillment

Ensure your webhook listener performs strict validation before updating your database:

<?php
// webhook_listener.php — Secure Webhook Callback
$rawInput = file_get_contents('php://input');
$data     = json_decode($rawInput, true);

$orderId = $data['order_id'] ?? null;
if (!$orderId) {
    http_response_code(400);
    exit('Missing order_id');
}

// 1. Verify with Gateway API
$verifyCh = curl_init('https://upigateway.dev/api/check-order-status');
curl_setopt_array($verifyCh, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => json_encode([
        'user_token' => UPIGATEWAY_TOKEN,
        'order_id'   => $orderId
    ]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json']
]);
$verifyRes = json_decode(curl_exec($verifyCh), true);
curl_close($verifyCh);

$isCompleted = ($verifyRes['status'] === true || $verifyRes['status'] === 'COMPLETED') &&
               (($verifyRes['result']['status'] ?? '') === 'COMPLETED');

if ($isCompleted) {
    // Mark order Paid in MySQL and trigger warehouse dispatch
    $stmt = $pdo->prepare("UPDATE orders SET payment_status = 'PAID', utr = ? WHERE order_number = ? AND payment_status != 'PAID'");
    $stmt->execute([$verifyRes['result']['utr'] ?? ($data['utr'] ?? ''), $orderId]);
    
    echo json_encode(['status' => 'SUCCESS']);
} else {
    http_response_code(400);
    echo json_encode(['status' => 'PENDING_OR_FAILED']);
}

Related Integration Guides & Developer Resources

Explore more technical articles, code examples, and architecture guides on our official blog. Automate your Indian payment collection at zero percent fees with UPIGateway.dev.

We provide comprehensive developer documentation, ready-to-deploy SDKs for PHP and Node.js, and plug-and-play e-commerce plugins for WordPress and WooCommerce. Build modern payment checkout flows with direct bank settlement and full financial autonomy.

Back to Blog Index | View API Documentation | Explore Pricing Plans