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

# PHP SDK

> Waffo PHP SDK installation, initialization, and usage guide.

## Requirements

* PHP 8.0+
* Composer
* PHP extensions: cURL, JSON, and OpenSSL

## Installation

```bash theme={null}
composer require waffo/waffo-php
```

<Note>
  The current latest version is `v0.3.0`. Check the latest version on [Packagist](https://packagist.org/packages/waffo/waffo-php) before you go live.
</Note>

## Initialization

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

require __DIR__ . '/vendor/autoload.php';

use Waffo\Config\Environment;
use Waffo\Config\WaffoConfig;
use Waffo\Waffo;

$waffo = new Waffo(new WaffoConfig(
    apiKey: 'your-api-key',
    privateKey: 'your-base64-private-key',
    waffoPublicKey: 'waffo-base64-public-key',
    environment: Environment::Sandbox,
    merchantId: 'your-merchant-id',
));
```

## Payment

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

$response = $waffo->order()->create([
    'paymentRequestId' => bin2hex(random_bytes(16)),
    'merchantOrderId' => 'ORDER-123',
    'orderCurrency' => 'HKD',
    'orderAmount' => '100.00',
    'orderDescription' => 'Premium Plan',
    'notifyUrl' => 'https://your-site.com/webhook/waffo',
    'successRedirectUrl' => 'https://your-site.com/payment/success',
    'failedRedirectUrl' => 'https://your-site.com/payment/failed',
    'cancelRedirectUrl' => 'https://your-site.com/payment/cancel',
    'userInfo' => ['userId' => 'user_123', 'userEmail' => 'user@example.com', 'userTerminal' => 'WEB'],
    'paymentInfo' => ['productName' => 'ONE_TIME_PAYMENT'],
    'goodsInfo' => ['goodsName' => 'Premium Plan', 'goodsUrl' => 'https://your-site.com/product/001'],
]);

if ($response->isSuccess()) {
    var_dump($response->data);
}
```

## Inquiry

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

$response = $waffo->order()->inquiry(['paymentRequestId' => 'payment-request-id']);

if ($response->isSuccess()) {
    var_dump($response->data);
}
```

## Subscription

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

$response = $waffo->subscription()->create(['subscriptionRequest' => 'sub-request-1', 'merchantSubscriptionId' => 'sub-1', 'currency' => 'USD', 'amount' => '9.99', 'notifyUrl' => 'https://example.com/webhooks/waffo', 'productInfo' => ['description' => 'Monthly plan', 'periodType' => 'MONTHLY', 'periodInterval' => '1'], 'userInfo' => ['userId' => 'user-1', 'userEmail' => 'user-1@example.com'], 'paymentInfo' => ['productName' => 'SUBSCRIPTION']]);

if ($response->isSuccess()) {
    var_dump($response->data);
}
```

### Query a subscription

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

$response = $waffo->subscription()->inquiry(['subscriptionRequest' => 'sub-request-1']);

if ($response->isSuccess()) {
    var_dump($response->data);
}
```

### Cancel a subscription

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

$response = $waffo->subscription()->cancel(['subscriptionId' => 'subscription-id']);

if ($response->isSuccess()) {
    var_dump($response->data);
}
```

## Refund

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

$response = $waffo->order()->refund(['refundRequestId' => 'refund-1', 'acquiringOrderId' => 'A123', 'refundAmount' => '10.00', 'refundReason' => 'Customer request']);

if ($response->isSuccess()) {
    var_dump($response->data);
}
```

### Query a refund

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

$response = $waffo->refund()->inquiry(['refundRequestId' => 'refund-1']);

if ($response->isSuccess()) {
    var_dump($response->data);
}
```

## Webhook handling

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

$result = $waffo->webhook()
    ->onPayment(static function (array $event): void {})
    ->onRefund(static function (array $event): void {})
    ->onSubscriptionStatus(static function (array $event): void {})
    ->onSubscriptionPeriodChanged(static function (array $event): void {})
    ->onSubscriptionChange(static function (array $event): void {})
    ->handleWebhook(file_get_contents('php://input'), $_SERVER['HTTP_X_SIGNATURE'] ?? null);
header('X-SIGNATURE: ' . $result->responseSignature);
echo $result->responseBody;
```

Your Webhook endpoint must pass the unmodified request body and `X-SIGNATURE` header to the SDK, then return the response body and `X-SIGNATURE` generated by the SDK.

## Error handling

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

use Waffo\Exception\WaffoUnknownStatusError;

try {
    $response = $waffo->order()->create($params);
} catch (WaffoUnknownStatusError $error) {
    $response = $waffo->order()->inquiry(['paymentRequestId' => $params['paymentRequestId']]);
}
```

## Package registry

* [Packagist](https://packagist.org/packages/waffo/waffo-php)
* [GitHub](https://github.com/waffo-com/waffo-php)
