Hosted Checkout — PHP

Step-by-step PHP for hosted checkout — create link, redirect, confirm, refund.

Step-by-step Hosted Checkout integration in PHP — create link, redirect, confirm, refund. Your server creates a payment link, redirects the customer to DigetPay, then confirms payment server-side.

Apple Pay, Mada, and 3-D Secure are handled on the DigetPay checkout page. You do not implement Apple Pay in PHP for hosted checkout — only send customerPhone when creating the link.

Prerequisites: Sandbox Setup, staging x-api-key, PHP 8.0+ with cURL enabled.


Architecture

sequenceDiagram
  participant Browser as Customer Browser
  participant Shop as Your PHP Store
  participant API as DigetPay API
  participant Checkout as DigetPay Checkout

  Browser->>Shop: Checkout (order total)
  Shop->>API: POST /payment/checkout/intiate
  API-->>Shop: redirectUrl
  Shop->>Browser: HTTP 302 redirect
  Browser->>Checkout: Pay (card / Mada / Apple Pay)
  Checkout->>Browser: Redirect successUrl / failureUrl
  Browser->>Shop: Return to your site
  Shop->>API: GET /payment/checkout/status
  API-->>Shop: transactionStatus

Step 1 — Configuration

Create config/digetpay.php:

<?php
declare(strict_types=1);

return [
    'environment' => getenv('DIGETPAY_ENV') ?: 'staging',
    'api_key' => getenv('DIGETPAY_API_KEY') ?: '',
    'environments' => [
        'staging' => [
            'api_base' => 'https://fin-api.digetpay.com/v1',
        ],
        'production' => [
            'api_base' => 'https://api.digetpay.com/v1',
        ],
    ],
];

.env example (never commit):

DIGETPAY_ENV=staging
DIGETPAY_API_KEY=your_fin_staging_key

Step 2 — API client

Create src/DigetPayClient.php:

<?php
declare(strict_types=1);

require_once __DIR__ . '/../src/DigetPayClient.php';

$config = require __DIR__ . '/../config/digetpay.php';
$client = new DigetPayClient($config);

// Gateway transaction ID — retrieved from your database after payment confirmation
// This is $content['id'] from the status API response (Step 5)
$transactionId = 'your-gateway-transaction-id-here';
$refundAmount = 5.00; // Partial refund — set to full order amount for a full refund

try {
    $result = $client->processRefund($transactionId, $refundAmount);
    echo 'Refund submitted successfully.';
    // TODO: Update the order status in your database
} catch (Throwable $e) {
    error_log('[DigetPay] processRefund error: ' . $e->getMessage());
    echo 'Refund request failed. Please try again or contact support.';
}

The path is spelled /payment/checkout/intiate on Fin and production — not /session.


Step 3 — Create payment link and redirect

public/checkout.php:

<?php
declare(strict_types=1);

require_once __DIR__ . '/../src/DigetPayClient.php';

$config = require __DIR__ . '/../config/digetpay.php';
$client = new DigetPayClient($config);

// Generate a unique order ID for this transaction
$orderId = 'ORD-' . time();
$amount = 10.00; // Amount in SAR

// Replace with your actual store URLs in production
$successUrl = 'https://yourstore.com/checkout/success';
$failureUrl = 'https://yourstore.com/checkout/failure';

try {
    $session = $client->createPaymentLink([
        'merchantOrderId' => $orderId,
        'amount' => $amount,
        'currency' => 'SAR',
        'customerName' => 'Ahmed Ali',
        'customerEmail' => '[email protected]',
        'customerPhone' => '501223324', // Required for Apple Pay on the checkout page
        'successUrl' => $successUrl,
        'failureUrl' => $failureUrl,
    ]);

    // IMPORTANT: Save the session ID and order ID to your database BEFORE redirecting.
    // You will need $session['id'] to verify payment when the customer returns.
    // saveOrderSession($orderId, $session['id']); // your DB call here

    // Redirect the customer to the DigetPay hosted checkout page
    header('Location: ' . $session['redirectUrl'], true, 302);
    exit;

} catch (Throwable $e) {
    http_response_code(500);
    echo 'Payment initiation failed. Please try again.';
    error_log('[DigetPay] createPaymentLink error: ' . $e->getMessage());
}

Apple Pay: DigetPay checkout displays Apple Pay when the customer uses Safari and customerPhone was sent. No additional PHP code required.


Step 4 — Handle return URLs (do not trust redirect alone)

public/checkout/success.php:

<?php
declare(strict_types=1);

// Customer has returned from checkout — payment is NOT confirmed yet.
// DigetPay appends the session ID to the URL as ?sessionId=...
$sessionId = $_GET['sessionId'] ?? null;

if ($sessionId === null) {
    http_response_code(400);
    echo 'Missing session information.';
    exit;
}

// TODO: Look up the stored order using $sessionId from your database
// $order = getOrderBySessionId($sessionId);

// TODO: Call the status API (Step 5) to verify payment before showing confirmation
echo '<p>Thank you! We are confirming your payment...</p>';
echo '<p>You will receive a confirmation email shortly.</p>';

Never mark an order paid based only on arrival at successUrl. Always confirm via status API or webhook.


Step 5 — Confirm payment (status API)

<?php
declare(strict_types=1);

require_once __DIR__ . '/../src/DigetPayClient.php';

$config = require __DIR__ . '/../config/digetpay.php';
$client = new DigetPayClient($config);

// Use the DigetPay session ID returned by createPaymentLink() — retrieved from your database
$sessionId = 'your-stored-session-id-here';

$response = $client->getTransactionStatus($sessionId);

$content = $response['data']['content'][0] ?? null;
if ($content && ($content['transactionStatus'] ?? '') === 'SUCCESS') {
    // Save $content['id'] as the gateway transaction ID — needed for refunds
    // markOrderPaid($orderId, $content['id']);
    echo 'Payment confirmed';
} elseif ($content && ($content['transactionStatus'] ?? '') === 'PENDING') {
    echo 'Payment is still processing. Please check back shortly.';
} else {
    echo 'Payment pending or failed';
}

See Query Transaction Status for response fields.


Step 6 — Webhook handler

public/webhooks/digetpay.php:

<?php
declare(strict_types=1);

$raw = file_get_contents('php://input');
if ($raw === false || $raw === '') {
    http_response_code(400);
    exit;
}

$payload = json_decode($raw, true);
if (!is_array($payload)) {
    http_response_code(400);
    exit;
}

// Always respond with 200 immediately to acknowledge receipt.
// DigetPay will retry delivery if it does not receive a 200 response.
http_response_code(200);
echo 'OK';

// Extract key fields from the webhook payload
$transactionId = $payload['transactionId'] ?? null; // Gateway transaction ID — use for refunds
$orderId = $payload['orderId'] ?? null;              // Your original merchantOrderId
$status = $payload['status'] ?? null;               // e.g. 'Approved', 'Declined'

error_log('[DigetPay webhook] ' . $raw);

// IMPORTANT: Use transactionId to deduplicate — webhooks may be delivered more than once.
// if (isAlreadyProcessed($transactionId)) { exit; }

if ($status === 'Approved' && $transactionId && $orderId) {
    // Mark the order as paid in your database
    // markOrderPaid($orderId, $transactionId);
}

// For full webhook event shapes and signature verification, see:
// Handle Webhooks guide → Verify Signatures guide →

Full details: Handle Webhooks, Verify Signatures.


Step 7 — Refund

<?php
declare(strict_types=1);

require_once __DIR__ . '/../src/DigetPayClient.php';

$config = require __DIR__ . '/../config/digetpay.php';
$client = new DigetPayClient($config);

$result = $client->processRefund(
    gatewayTransactionId: '2232e99b-0257-47d5-bbfd-022c8951767f',
    amount: 5.00
);

Process Refund guide →


Staging vs production

SettingStagingProduction
DIGETPAY_ENVstagingproduction
API basefin-api.digetpay.com/v1api.digetpay.com/v1
API keyFin staging keyProduction key

Environments Overview →


What you do NOT need in PHP (hosted checkout)

FeatureWhere it happens
Apple Pay buttonDigetPay checkout page
Mada / card formDigetPay checkout page
3-D SecureDigetPay checkout page
PCI card storageDigetPay infrastructure

Next steps



Did this page help you?