Skip to content

liedekef/payconiq-api-php

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

85 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Payconiq API client for PHP

Accepting Payconiq payments with the use of the QR code.
API documentation can be found here.

Requirements

To use the Payconiq API client, the following things are required:

  • Payconiq Merchant Id and API key
  • PHP >= 8.3
  • PHP cURL extension

Installation

The best way to install the Payconiq API client is to require it with Composer.

$ composer require liedekef/payconiq-api-php

You may also git checkout or download all the files, and include the Payconiq API client manually.

Parameters

We use the following parameters in the examples below:

$apiKey = 'apiKey 123456'; // Used to secure request between merchant backend and Payconiq backend.
$merchantId = 'merchantid'; // payconiq merchantid (not really used, unless to verify more in notification callback)
$amount = 1000; // Transaction amount in cents
$currency = 'EUR'; // Currency
$reference = "my internal payment reference"; // an internal reference (e.g. a booking id)
      // the reference is given in the callback, allowing you to know what local payment is being handled
$callbackUrl = 'http://yoursite.com/postback'; // Callback where Payconiq needs to POST confirmation status
$returnUrl = 'http://yoursite.com/returnpage'; // Optional. the page a buyer is returned to after payment. You'll need to check
     // the payment status there

To learn more about how, when and what Payconiq will POST to your callbackUrl, please refer to the developer documentation right here.

Installation

// Include the Client.php file
require_once '/path/to/Payconiq/Client.php';

use Payconiq\Client;

Initialization

Basic Setup

// Production environment (default)
$client = new Client('your-api-key-here');

// Test environment
$client = new Client('your-test-api-key', Client::ENVIRONMENT_TEST);

// Or configure after instantiation
$client = new Client();
$client->setApiKey('your-api-key-here')
       ->setEndpointTest(); // Switch to test environment

Custom Endpoints

$client->setEndpoints(
    'https://custom.api.endpoint/v3',
    'https://custom.jwks.endpoint/'
);

Core Methods

1. Create a Payment

/**
 * @param float $amount Payment amount in cents (e.g., 1000 = €10.00)
 * @param string $currency Currency code (default: 'EUR')
 * @param string $description Payment description (optional, max 140 chars)
 * @param string $reference External reference (optional, max 35 chars)
 * @param string $bulkId Bulk ID for payouts (optional)
 * @param string $callbackUrl Webhook callback URL (optional)
 * @param string $returnUrl Return URL after payment (optional)
 * @return object Payment object with paymentId
 * @throws CreatePaymentFailedException
 */
$payment = $client->createPayment(
    1000,                   // €10.00
    'EUR',                  // Currency
    'Order #12345',         // Description
    'REF-12345',            // Your reference
    '',                     // Bulk ID
    'https://your-site.com/webhook',
    'https://your-site.com/return'
);

// Response contains:
// - $payment->paymentId
// - $payment->_links->checkout->href (payment URL for customer)

2. Retrieve Payment Details

/**
 * @param string $paymentId Payconiq payment ID
 * @return object Payment details
 * @throws RetrievePaymentFailedException
 */
$payment = $client->retrievePayment('PAYMENT_ID_HERE');

// Response contains:
// - $payment->paymentId
// - $payment->amount
// - $payment->currency
// - $payment->status (e.g., 'SUCCEEDED', 'PENDING')
// - $payment->_links->refund->href (if refundable)

3. Get Payments by Reference

/**
 * @param string $reference Your external reference
 * @return array List of payments with matching reference
 * @throws GetPaymentsListFailedException
 */
$payments = $client->getPaymentsListByReference('REF-12345');

// Returns array of payment objects

4. Get Payments by Date Range

/**
 * @param string $fromDate Start date (format: YYYY-MM-ddTHH:mm:ss.SSSZ)
 * @param string $toDate End date (format: YYYY-MM-ddTHH:mm:ss.SSSZ)
 * @param int $size Page size (default: 50)
 * @return array List of successful payments in date range
 * @throws GetPaymentsListFailedException
 */
$payments = $client->getPaymentsListByDateRange(
    '2024-01-01T00:00:00.000Z',
    '2024-01-31T23:59:59.999Z',
    100
);

5. Refund a Payment

/**
 * @param string $paymentId Payconiq payment ID
 * @param float $amount Refund amount in cents
 * @param string $currency Currency (default: 'EUR')
 * @param string $description Refund description (optional)
 * @param string $idempotencyKey Optional idempotency key (UUIDv4)
 * @param string $refundUrl Optional custom refund URL
 * @return object Refund response
 * @throws RefundFailedException
 */
$refund = $client->refundPayment(
    'PAYMENT_ID_HERE',
    500,                    // Refund €5.00
    'EUR',
    'Partial refund for order #12345',
    null,                   // Auto-generated UUID if null
    null                    // Auto-detected from payment
);

6. Get Refund IBAN

/**
 * @param string $paymentId Payconiq payment ID
 * @return string IBAN for refunds
 * @throws GetRefundIbanFailedException
 */
$iban = $client->getRefundIban('PAYMENT_ID_HERE');

Webhook Signature Verification

1. Verify Webhook Signature

/**
 * @param string $payload Raw request body (php://input)
 * @param array $headers HTTP headers (getallheaders())
 * @return bool True if signature is valid
 * @throws \Exception on verification failure
 */
$isValid = $client->verifyWebhookSignature(
    file_get_contents('php://input'),
    getallheaders()
);

if ($isValid) {
    // Process webhook
    $data = json_decode(file_get_contents('php://input'), true);
    // Handle payment events
}

2. Webhook Handling Example

// Complete webhook handler example
try {
    $payload = file_get_contents('php://input');
    $headers = getallheaders();
    
    if ($client->verifyWebhookSignature($payload, $headers)) {
        $data = json_decode($payload, true);
        
        switch ($data['status']) {
            case 'SUCCEEDED':
                // Update order as paid
                break;
            case 'FAILED':
                // Handle failed payment
                break;
            case 'REFUNDED':
                // Handle refund
                break;
        }
        
        http_response_code(200);
        echo 'OK';
    } else {
        http_response_code(401);
        echo 'Invalid signature';
    }
} catch (\Exception $e) {
    error_log('Webhook error: ' . $e->getMessage());
    http_response_code(400);
}

Error Handling

Exception Types

  • CreatePaymentFailedException
  • RetrievePaymentFailedException
  • GetPaymentsListFailedException
  • RefundFailedException
  • GetRefundIbanFailedException

Exception Example

try {
    $payment = $client->createPayment(1000, 'EUR');
} catch (CreatePaymentFailedException $e) {
    echo 'Payment creation failed: ' . $e->getMessage();
} catch (\Exception $e) {
    echo 'General error: ' . $e->getMessage();
}

Common Error Responses

// Check response for details
$response = $client->createPayment(1000, 'EUR');
if (isset($response->message)) {
    // API returned an error message
    echo 'Error: ' . $response->message;
}

Utility Methods

Get Environment

$environment = $client->getEnvironment(); // 'prod' or 'test'

Set Cache Directory for JWKS Keys

// If not set, the system tmp dir is used
$client->setCacheDir('/my/own/dir');

SEPA String Conversion

All strings (descriptions, references) are automatically converted to SEPA-compliant format:

  • Removes diacritics/accents
  • Filters to allowed characters only
  • Truncates to maximum lengths

Best Practices

1. Idempotency for Refunds

// Always use idempotency keys for refunds
$idempotencyKey = 'unique-refund-key-' . time();
$client->refundPayment($paymentId, $amount, 'EUR', '', $idempotencyKey);

2. Webhook Security

  • Always verify webhook signatures
  • Never process unverified webhooks
  • Implement replay attack protection

3. Cache Management

  • JWKS keys are cached automatically
  • Cache is refreshed on verification failures
  • Cache refresh is done in a way to avoid hitting the jwks-servers too hard
  • Cache directory can be set via method

Note: This client automatically handles SEPA compliance, JWKS caching, and signature verification according to Payconiq specifications.

About

Unofficial Payconiq API client for PHP

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 97.8%
  • Shell 2.2%