Trust Gateway
Home/Guides/PHP
TRUST GATEWAY GUIDE

PHP UPI Payment Integration: Create a Trust Gateway Checkout with cURL

Connect a PHP backend to Trust Gateway with server-side cURL, a saved order mapping and authenticated payment verification.

A PHP shop can use Trust Gateway without moving payment decisions into browser code. PHP creates the request, stores its reference and redirects the buyer to hosted checkout. This guide focuses on that boundary: what to send, what to save, and how to handle an HTTP response that never arrives.

Prepare your PHP environment

Your host needs PHP with cURL enabled, outbound HTTPS access and a database for local purchases. Configure a supported receiving account and an active merchant subscription before testing. Put the merchant key in a server environment variable named TRUST_GATEWAY_API_KEY. On shared hosting, check how environment variables reach the PHP web process; a shell variable may not automatically be available to a web request.

Fail clearly when configuration is missing. Do not insert the key into JavaScript as a workaround. Record a private configuration error and show the customer that checkout is temporarily unavailable. The API key guide explains storage and rotation.

Send a server-side JSON request

This PHP fragment demonstrates the HTTP call only. It assumes that your backend has authenticated the buyer and calculated a trusted price. It is not a complete shopping cart or retry implementation.

$key = getenv('TRUST_GATEWAY_API_KEY');
if (!$key) {
    throw new RuntimeException('Payment configuration unavailable');
}
$ch = curl_init('https://trustgateway.in/api/v1/orders/create');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-API-Key: ' . $key,
    ],
    CURLOPT_POSTFIELDS => json_encode(['amount' => '499.00'], JSON_THROW_ON_ERROR),
]);
$raw = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$transportFailed = ($raw === false);
curl_close($ch);
if ($transportFailed) {
    throw new RuntimeException('Payment creation outcome needs review');
}
$result = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
if ($http < 200 || $http >= 300 || empty($result['success'])) {
    throw new RuntimeException('Checkout could not be created');
}
$gatewayOrder = $result['data'];

Keep TLS certificate verification enabled. Catch transport, JSON and application errors at the controller boundary without showing secrets or raw responses to customers. Replace the example price with your server-calculated amount, not an unchecked browser value.

Save before redirecting

Persist data.order_id, data.amount, data.requested_amount, data.checkout_url and expiry beside the local purchase. A matching adjustment can make the payable amount differ from the requested amount, so retain both. Validate the returned relative checkout path and compose the redirect using the fixed Trust Gateway origin. Do not let a buyer supply an arbitrary destination.

Verify the reference from your database

Call GET /api/v1/orders/status/:order_id from PHP with the same X-API-Key header. Load the gateway reference from the authenticated buyer's local purchase. Require a successful HTTP response, paid: true and authenticated details matching the stored order ID and payable amount. Compare amounts as integer paise rather than loose floating-point values.

Protect fulfilment with a database transaction and a unique gateway reference so two PHP workers cannot issue the same benefit twice. The status documentation describes the response fields.

Treat timeouts as uncertain outcomes

A failed connection does not prove the gateway never created an order. Keep a local attempt record and avoid a blind create loop. If a reference was saved, verify it. If no response arrived, investigate before offering another payable checkout. Test invalid JSON, unavailable receiving accounts and an unpaid return to your store using the launch checklist.