Server

PHP SDK

Drop-in PHP implementation for integrating YardPay Pro into server-side applications. Uses cURL — no Composer packages required.

API Client

Create YardPayProClient.php

<?php
// YardPayProClient.php

class YppException extends Exception
{
    public int $status;
    public string $code;

    public function __construct(int $status, string $code, string $message)
    {
        parent::__construct($message);
        $this->status = $status;
        $this->code = $code;
    }
}

class YardPayProClient
{
    private string $apiKey;
    private string $baseUrl;
    private int $timeout;

    public function __construct(string $apiKey, string $baseUrl = '', int $timeout = 30)
    {
        $this->apiKey = $apiKey;
        $this->baseUrl = rtrim($baseUrl, '/');
        $this->timeout = $timeout;
    }

    public function request(string $method, string $path, ?array $body = null, ?array $params = null): mixed
    {
        $url = $this->baseUrl . $path;
        if ($params) {
            $url .= '?' . http_build_query($params);
        }

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => $this->timeout,
            CURLOPT_CUSTOMREQUEST => $method,  // GET, POST, PUT, DELETE
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json',
                'x-api-key: ' . $this->apiKey,
            ],
        ]);

        if ($body !== null) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
        }

        $response = curl_exec($ch);
        $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curlError = curl_error($ch);
        curl_close($ch);

        if ($curlError) {
            throw new YppException(0, 'network_error', $curlError);
        }

        if ($statusCode === 204) {
            return null;
        }

        if ($statusCode >= 400) {
            $err = json_decode($response, true) ?? [];
            throw new YppException(
                $statusCode,
                $err['code'] ?? 'api_error',
                $err['message'] ?? "HTTP $statusCode"
            );
        }

        $data = json_decode($response, true);

        // Handle OData { "value": [...] } wrapper
        if (is_array($data) && array_key_exists('value', $data)) {
            return $data['value'];
        }

        return $data;
    }

    public function get(string $path, ?array $params = null): mixed
    {
        return $this->request('GET', $path, null, $params);
    }

    public function post(string $path, array $body): mixed
    {
        return $this->request('POST', $path, $body);
    }

    public function put(string $path, array $body): mixed
    {
        return $this->request('PUT', $path, $body);
    }

    public function delete(string $path): mixed
    {
        return $this->request('DELETE', $path);
    }
}
Services

Create YardPayProServices.php

<?php
// YardPayProServices.php

require_once __DIR__ . '/YardPayProClient.php';

class PaymentsService
{
    private YardPayProClient $client;

    public function __construct(YardPayProClient $client)
    {
        $this->client = $client;
    }

    /** Pay an invoice with card or saved funding source */
    public function payInvoice(array $data): array
    {
        return $this->client->post('/api/payment/payinvoice', $data);
    }

    /** Get available payment methods for an invoice */
    public function getPaymentMethods(int $invoiceId): array
    {
        return $this->client->get("/v1/invoice/$invoiceId/PaymentMethods");
    }

    /** List saved funding sources */
    public function getFundingSources(): array
    {
        return $this->client->get('/v1/FundingSource');
    }

    /** Register a new card */
    public function registerCard(array $card, string $name): array
    {
        return $this->client->post('/v1/payment/RegisterCard', [
            'card' => $card,
            'name' => $name,
        ]);
    }

    /** Verify a registered card */
    public function verifyCard(int $fundingSourceId, string $code): void
    {
        $this->client->post("/v1/fundingSource/$fundingSourceId/verify", [
            'VerificationCode' => $code,
        ]);
    }
}

class InvoicesService
{
    private YardPayProClient $client;

    public function __construct(YardPayProClient $client)
    {
        $this->client = $client;
    }

    /** Get invoice by public reference code (no auth needed) */
    public function getByReference(string $code): array
    {
        return $this->client->get("/v1/invoice/getByReference(code='$code')");
    }

    /** Get invoice by ID */
    public function getById(int $id, ?string $expand = null): array
    {
        $params = $expand ? ['$expand' => $expand] : null;
        return $this->client->get("/v1/invoice/$id", $params);
    }

    /** List invoices with OData filtering */
    public function list(?string $filter = null, ?string $orderBy = null, int $top = 20, int $skip = 0): array
    {
        $params = ['$top' => $top, '$skip' => $skip];
        if ($filter) $params['$filter'] = $filter;
        if ($orderBy) $params['$orderby'] = $orderBy;
        return $this->client->get('/v1/invoice', $params);
    }

    /** Create a new invoice */
    public function create(array $data): array
    {
        return $this->client->post('/v1/invoice', $data);
    }

    /** Get QR code URL */
    public function getQrCodeUrl(string $identifier, string $baseUrl = ''): string
    {
        return "$baseUrl/v1/invoice/qrcode/$identifier";
    }
}

class SubscriptionsService
{
    private YardPayProClient $client;

    public function __construct(YardPayProClient $client)
    {
        $this->client = $client;
    }

    // Products
    public function listProducts(?array $params = null): array { return $this->client->get('/v1/SubscriptionProduct', $params); }
    public function createProduct(array $data): array { return $this->client->post('/v1/SubscriptionProduct', $data); }
    public function updateProduct(int $id, array $data): array { return $this->client->put("/v1/SubscriptionProduct/$id", $data); }
    public function deleteProduct(int $id): void { $this->client->delete("/v1/SubscriptionProduct/$id"); }

    // Plans
    public function listPlans(?array $params = null): array { return $this->client->get('/v1/SubscriptionPlan', $params); }
    public function createPlan(array $data): array { return $this->client->post('/v1/SubscriptionPlan', $data); }
    public function updatePlan(int $id, array $data): array { return $this->client->put("/v1/SubscriptionPlan/$id", $data); }
    public function deletePlan(int $id): void { $this->client->delete("/v1/SubscriptionPlan/$id"); }

    // Inventory
    public function listInventory(?array $params = null): array { return $this->client->get('/v1/SubscriptionInventoryItem', $params); }
    public function createInventoryItem(array $data): array { return $this->client->post('/v1/SubscriptionInventoryItem', $data); }
    public function updateInventoryItem(int $id, array $data): array { return $this->client->put("/v1/SubscriptionInventoryItem/$id", $data); }
    public function deleteInventoryItem(int $id): void { $this->client->delete("/v1/SubscriptionInventoryItem/$id"); }
}
Usage
<?php
require_once __DIR__ . '/YardPayProServices.php';

$client = new YardPayProClient('sk_test_YOUR_KEY');
$payments = new PaymentsService($client);
$invoices = new InvoicesService($client);

// Create an invoice
$invoice = $invoices->create([
    'description' => 'Order #1234',
    'currencyCode' => 'JMD',
    'items' => [
        ['name' => 'Widget', 'unitCost' => 100, 'quantity' => 2, 'invoiceItemTypeId' => 'Product'],
    ],
    'sourceInfo' => [
        'firstName' => 'Test',
        'lastName' => 'User',
        'email' => '[email protected]',
    ],
]);

echo "Invoice: " . $invoice['identifier'] . PHP_EOL;

// Get payment methods
$methods = $payments->getPaymentMethods($invoice['id']);
$cardMethod = array_values(array_filter($methods, fn($m) => $m['paymentMethodId'] === 'CreditCard'))[0];

// Pay the invoice
$result = $payments->payInvoice([
    'invoiceIdentifier' => $invoice['identifier'],
    'paymentOptionId' => $cardMethod['id'],
    'card' => [
        'name' => 'Test User',
        'cardNumber' => '4111111111111111',
        'expiryDate' => '12/28',
        'cvv' => '123',
    ],
]);

if ($result['isSuccess']) {
    echo "Paid: " . $result['referenceNumber'] . PHP_EOL;
}
Webhook Signature Verification
<?php
// webhook.php

function verifyWebhookSignature(string $payload, string $signature, string $secret): bool
{
    $expected = hash_hmac('sha256', $payload, $secret);
    return hash_equals($expected, $signature);
}

// Handle incoming webhook
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_YPP_SIGNATURE'] ?? '';
$secret = getenv('YARDPAYPRO_WEBHOOK_SECRET');

if (!verifyWebhookSignature($payload, $signature, $secret)) {
    http_response_code(401);
    exit('Invalid signature');
}

$event = json_decode($payload, true);

switch ($event['type']) {
    case 'payment.completed':
        $paymentId = $event['data']['referenceNumber'];
        // Handle completed payment
        break;

    case 'invoice.paid':
        $invoiceId = $event['data']['id'];
        // Handle paid invoice
        break;
}

http_response_code(200);
Error Handling
try {
    $result = $payments->payInvoice([...]);
} catch (YppException $e) {
    switch ($e->status) {
        case 401:
            echo "Invalid API key" . PHP_EOL;
            break;
        case 403:
            echo "Insufficient scope: " . $e->code . PHP_EOL;
            break;
        case 400:
            echo "Validation error: " . $e->getMessage() . PHP_EOL;
            break;
        default:
            echo "API error {$e->status}: {$e->getMessage()}" . PHP_EOL;
    }
}
Requirements
  • PHP 8.1+
  • ext-curl and ext-json (standard in most PHP installations)
  • No Composer packages required — copy the files into your project
  • Works with any PHP framework (Laravel, Symfony, WordPress, etc.)