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
customerPhonewhen 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_keyStep 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/intiateon 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
customerPhonewas 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
);Staging vs production
| Setting | Staging | Production |
|---|---|---|
DIGETPAY_ENV | staging | production |
| API base | fin-api.digetpay.com/v1 | api.digetpay.com/v1 |
| API key | Fin staging key | Production key |
What you do NOT need in PHP (hosted checkout)
| Feature | Where it happens |
|---|---|
| Apple Pay button | DigetPay checkout page |
| Mada / card form | DigetPay checkout page |
| 3-D Secure | DigetPay checkout page |
| PCI card storage | DigetPay infrastructure |
Next steps
Updated about 1 month ago
