> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oneclickdz.com/llms.txt
> Use this file to discover all available pages before exploring further.

# PHP SDK Integration

> Quick setup guide for Navio PHP SDK

## Overview

The Navio PHP SDK provides a modern, type-safe interface for integrating Navio payments into your PHP applications. Built with PHP 8.1+ features and best practices.

<CardGroup cols={2}>
  <Card title="Type Safe" icon="shield-check" color="#0D9373">
    Full PHP 8.1+ type hints and return types
  </Card>

  <Card title="Composer Ready" icon="box" color="#0D9373">
    PSR-4 autoloading and easy installation
  </Card>

  <Card title="Simple API" icon="code" color="#0D9373">
    Clean, intuitive interface
  </Card>

  <Card title="Error Handling" icon="circle-exclamation" color="#0D9373">
    Custom exceptions for different error types
  </Card>
</CardGroup>

## Requirements

* PHP 8.1 or higher
* Composer
* `ext-json` extension
* `ext-curl` extension

## Installation

Install via Composer:

```bash theme={null}
composer require oneclickdz/ocpay-php-sdk
```

Or add to your `composer.json`:

```json theme={null}
{
    "require": {
        "oneclickdz/ocpay-php-sdk": "^1.0"
    }
}
```

## Quick Start

### 1. Initialize SDK

```php theme={null}
<?php

require 'vendor/autoload.php';

use OneClickDz\OCPay\OCPay;

// Initialize with your API access token
$ocpay = new OCPay('your-api-access-token');
```

<Warning>
  Store your API key in environment variables, never in code
</Warning>

```bash theme={null}
# .env file
ONECLICK_API_KEY=your_api_key_here
```

```php theme={null}
// Load from environment
$ocpay = new OCPay(getenv('ONECLICK_API_KEY'));
```

### 2. Create Payment Link

```php theme={null}
use OneClickDz\OCPay\DTO\CreateLinkRequest;
use OneClickDz\OCPay\DTO\ProductInfo;

// Create product information
$productInfo = new ProductInfo(
    title: 'Premium Subscription',
    amount: 5000, // Amount in DZD (500 - 500,000)
    description: 'Monthly access to premium features'
);

// Create payment link request
$request = new CreateLinkRequest(
    productInfo: $productInfo,
    feeMode: CreateLinkRequest::FEE_MODE_NO_FEE,
    successMessage: 'Thank you for your purchase!',
    redirectUrl: 'https://yourstore.com/success?order=12345'
);

// Create the payment link
try {
    $response = $ocpay->createLink($request);
    
    // Redirect customer to payment page
    echo "Payment URL: " . $response->paymentUrl . "\n";
    
    // IMPORTANT: Save this reference!
    echo "Payment Reference: " . $response->paymentRef . "\n";
    saveOrderPaymentRef($orderId, $response->paymentRef);
    
} catch (\OneClickDz\OCPay\Exception\ValidationException $e) {
    echo "Validation error: " . $e->getMessage() . "\n";
} catch (\OneClickDz\OCPay\Exception\UnauthorizedException $e) {
    echo "Auth error: " . $e->getMessage() . "\n";
} catch (\OneClickDz\OCPay\Exception\ApiException $e) {
    echo "API error: " . $e->getMessage() . "\n";
}
```

### 3. Check Payment Status

```php theme={null}
// Check payment status using the payment reference
try {
    $status = $ocpay->checkPayment('OCPL-A1B2C3-D4E5');
    
    if ($status->isConfirmed()) {
        // Payment successful - fulfill the order
        echo "Payment confirmed!\n";
        echo "Amount: " . $status->transactionDetails->amount . " DZD\n";
        fulfillOrder($orderId);
        
    } elseif ($status->isFailed()) {
        // Payment failed or expired
        echo "Payment failed: " . $status->message . "\n";
        markOrderFailed($orderId);
        
    } else {
        // Still pending - check again later
        echo "Payment pending...\n";
    }
    
} catch (\OneClickDz\OCPay\Exception\NotFoundException $e) {
    echo "Payment not found\n";
} catch (\OneClickDz\OCPay\Exception\PaymentExpiredException $e) {
    echo "Payment link expired\n";
} catch (\OneClickDz\OCPay\Exception\ApiException $e) {
    echo "API error: " . $e->getMessage() . "\n";
}
```

## Complete E-commerce Example

Here's a complete flow for an e-commerce checkout:

```php theme={null}
<?php

require 'vendor/autoload.php';

use OneClickDz\OCPay\OCPay;
use OneClickDz\OCPay\DTO\CreateLinkRequest;
use OneClickDz\OCPay\DTO\ProductInfo;

// Initialize SDK
$ocpay = new OCPay(getenv('ONECLICK_API_KEY'));

// Step 1: Create order in your system
$orderId = createOrder([
    'customer_id' => 123,
    'items' => [
        ['name' => 'Product A', 'price' => 5000],
        ['name' => 'Product B', 'price' => 3000],
    ],
    'total' => 8000,
]);

// Step 2: Create payment link
try {
    $productInfo = new ProductInfo(
        title: "Order #{$orderId}",
        amount: 8000,
        description: "Payment for order #{$orderId}"
    );
    
    $request = new CreateLinkRequest(
        productInfo: $productInfo,
        feeMode: CreateLinkRequest::FEE_MODE_NO_FEE,
        successMessage: "Thank you! Order #{$orderId} confirmed.",
        redirectUrl: "https://yourstore.com/orders/{$orderId}/success"
    );
    
    $response = $ocpay->createLink($request);
    
    // Step 3: Save payment reference
    updateOrder($orderId, [
        'payment_ref' => $response->paymentRef,
        'payment_url' => $response->paymentUrl,
        'status' => 'pending_payment',
    ]);
    
    // Step 4: Redirect customer
    header("Location: " . $response->paymentUrl);
    exit;
    
} catch (ApiException $e) {
    error_log("Payment creation failed: " . $e->getMessage());
    showErrorPage("Failed to create payment. Please try again.");
}
```

### Background Job for Status Polling

Set up a cron job or background worker:

```php theme={null}
<?php

// check_payments.php - Run every 20 minutes

require 'vendor/autoload.php';

use OneClickDz\OCPay\OCPay;

$ocpay = new OCPay(getenv('ONECLICK_API_KEY'));

// Get all pending orders
$pendingOrders = getPendingOrders();

foreach ($pendingOrders as $order) {
    if (!$order['payment_ref']) {
        continue;
    }
    
    try {
        $status = $ocpay->checkPayment($order['payment_ref']);
        
        if ($status->isConfirmed()) {
            // Mark as paid and fulfill
            updateOrder($order['id'], [
                'status' => 'paid',
                'paid_at' => date('Y-m-d H:i:s'),
            ]);
            fulfillOrder($order['id']);
            
        } elseif ($status->isFailed()) {
            // Mark as failed
            updateOrder($order['id'], [
                'status' => 'payment_failed',
            ]);
        }
        
    } catch (ApiException $e) {
        error_log("Status check failed: " . $e->getMessage());
    }
}
```

Add to crontab:

```bash theme={null}
*/20 * * * * php /path/to/check_payments.php
```

## API Reference

### OCPay Class

Main SDK entry point.

#### Constructor

```php theme={null}
public function __construct(
    string $accessToken,
    array $options = []
)
```

**Parameters:**

* `$accessToken`: Your API access token
* `$options`: Optional Guzzle client configuration
  * `timeout`: Request timeout in seconds (default: 30)

#### Methods

**createLink(CreateLinkRequest \$request): CreateLinkResponse**

Creates a payment link.

**checkPayment(string \$paymentRef): CheckPaymentResponse**

Checks payment status.

### Data Transfer Objects (DTOs)

#### ProductInfo

```php theme={null}
new ProductInfo(
    title: string,        // Product name (1-200 chars)
    amount: int,          // Amount in DZD (500 - 500,000)
    description?: string  // Optional (max 1000 chars)
)
```

#### CreateLinkRequest

```php theme={null}
new CreateLinkRequest(
    productInfo: ProductInfo,
    feeMode?: string,        // NO_FEE (default), SPLIT_FEE, CUSTOMER_FEE
    successMessage?: string, // Optional success message
    redirectUrl?: string     // Optional redirect URL
)
```

**Fee Mode Constants:**

* `CreateLinkRequest::FEE_MODE_NO_FEE` - Merchant pays (default)
* `CreateLinkRequest::FEE_MODE_SPLIT_FEE` - 50/50 split
* `CreateLinkRequest::FEE_MODE_CUSTOMER_FEE` - Customer pays

#### CreateLinkResponse

```php theme={null}
$response->paymentUrl     // URL to redirect customer
$response->paymentRef     // Payment reference (SAVE THIS!)
$response->paymentLink    // Full payment link object
```

#### CheckPaymentResponse

```php theme={null}
$response->status                // PaymentStatus enum
$response->message               // Status message
$response->paymentRef           // Payment reference
$response->transactionDetails   // Transaction details (if confirmed)

// Helper methods
$response->isConfirmed()        // true if payment confirmed
$response->isPending()          // true if still pending
$response->isFailed()           // true if failed
```

### Exception Handling

All exceptions extend `OCPayException`:

| Exception                 | HTTP Code | When Thrown            |
| ------------------------- | --------- | ---------------------- |
| `ValidationException`     | 400       | Invalid request data   |
| `UnauthorizedException`   | 403       | Invalid API key        |
| `NotFoundException`       | 404       | Payment not found      |
| `PaymentExpiredException` | 410       | Link expired (>20 min) |
| `ApiException`            | Various   | Other API errors       |

All exceptions provide:

```php theme={null}
try {
    $response = $ocpay->createLink($request);
} catch (ApiException $e) {
    echo $e->getMessage();       // Error message
    echo $e->getStatusCode();    // HTTP status code
    echo $e->getRequestId();     // Request ID for support
    var_dump($e->getErrorData()); // Full error data
}
```

## Important Notes

### Merchant Validation Required

<Warning>
  Complete merchant validation at [app.oneclickdz.com](https://app.oneclickdz.com/profile) before using the API
</Warning>

### Amount Limits

* **Minimum**: 500 DZD
* **Maximum**: 500,000 DZD
* Must be whole numbers (integers)

### Fee Structure

<Info>
  **Low Fees**: 0% on balance, only 1% withdrawal fee
</Info>

### Payment Link Expiration

Links expire **20 minutes** after creation if payment not initiated.

### Payment Status Flow

1. **PENDING** - Payment in progress → Poll again later
2. **CONFIRMED** - Payment successful → Fulfill order
3. **FAILED** - Payment declined/expired → Mark order failed

## Laravel Integration

For Laravel projects, see the complete integration example in the [GitHub repository](https://github.com/oneclickdz/ocpay-php-sdk/tree/main/examples/laravel).

Includes:

* Service provider setup
* Payment service class
* Controller examples
* Database migrations
* Background job for polling
* Error handling

## Testing

### Using Sandbox

The API automatically uses sandbox mode for test accounts:

```php theme={null}
$response = $ocpay->createLink($request);

if ($response->paymentLink->isSandbox) {
    echo "This is a test payment\n";
}
```

### Unit Tests

```bash theme={null}
composer install --dev
vendor/bin/phpunit
```

## Best Practices

<AccordionGroup>
  <Accordion title="Always Save Payment Reference" icon="database">
    Store `paymentRef` immediately after creating the link. You need it to check payment status.
  </Accordion>

  <Accordion title="Poll Payment Status" icon="clock">
    Set up a background job to check payment status every 20 minutes for pending orders.
  </Accordion>

  <Accordion title="Handle All Exceptions" icon="shield-halved">
    Catch and handle all exception types appropriately. Log errors for debugging.
  </Accordion>

  <Accordion title="Secure Your API Key" icon="key">
    Store API keys in environment variables, never commit them to version control.
  </Accordion>

  <Accordion title="Use HTTPS Only" icon="lock">
    Always use HTTPS for redirect URLs and your application endpoints.
  </Accordion>
</AccordionGroup>

## Support & Resources

<CardGroup cols={2}>
  <Card title="GitHub Repository" icon="github" href="https://github.com/oneclickdz/ocpay-php-sdk">
    Source code, examples, and issues
  </Card>

  <Card title="API Documentation" icon="book" href="/en/api-reference/ocpay/create-link">
    Detailed API reference
  </Card>

  <Card title="Laravel Example" icon="code" href="https://github.com/oneclickdz/ocpay-php-sdk/tree/main/examples/laravel">
    Complete Laravel integration
  </Card>

  <Card title="Contact Support" icon="headset" href="/en/contact">
    Get help from our team
  </Card>
</CardGroup>

## Next Steps

<Card title="Navio Best Practices" icon="star" href="/en/ocpay-guides/4-best-practices">
  Learn production-ready tips and security best practices
</Card>
