İyzipay (Iyzico) Integration

The artiframe add iyzico extension uses Iyzico's official PHP SDK (iyzico/iyzipay-php) to streamline complex processes such as Virtual POS, 3D Secure, Card Vault, and Marketplace into a single, smooth class (src/Service/Iyzico.php). All methods are designed with a standard response architecture (status, message, data) to ensure consistency at the API level.

1. Installation and Configuration

Include the extension into your project via the terminal:

terminal
$ artiframe add iyzico

After running this command, the following variables will be added to your .env file in the project root. You must populate them with the credentials obtained from your Iyzico Sandbox or production dashboard:

terminal
IYZICO_API_KEY=sandbox-api-key
IYZICO_SECRET_KEY=sandbox-secret-key
IYZICO_BASE_URL=https://sandbox-api.iyzipay.com
Tip: When you instantiate the class (new Iyzico()), authentication happens automatically in the background using the values from the .env file. The \Iyzipay\Options object is generated for you.
2. Standard Payment (Non-3D)

This method takes credit card details and executes a direct charge. The Iyzico infrastructure mandates that item breakdowns (basket items) and buyer details are submitted.

example.php
<?php
use Src\Service\Iyzico;

$iyzico = new Iyzico();

$response = $iyzico->pay([
    'price'       => 100.0,
    'paidPrice'   => 100.0,
    'currency'    => 'TRY',
    'installment' => 1,
    'card' => [
        'holder' => 'John Doe',
        'number' => '4546710000000000',
        'month'  => '12',
        'year'   => '2025',
        'cvc'    => '123'
    ],
    'buyer' => [
        'id'      => 'USR-100',
        'name'    => 'John',
        'surname' => 'Doe',
        'email'   => '[email protected]',
        'phone'   => '+905554443322',
        'ip'      => '85.34.78.112',
        'city'    => 'Istanbul',
        'country' => 'Turkey',
        'address' => 'Nidakule Göztepe, Merdivenköy Mah. Bora Sok. No:1',
        'zipCode' => '34732'
    ],
    'items' => [
        ['id' => 'ITEM-1', 'name' => 'Premium Membership', 'category' => 'Subscription', 'price' => 50.0],
        ['id' => 'ITEM-2', 'name' => 'E-Book', 'category' => 'Digital', 'price' => 50.0]
    ]
]);

if ($response['status'] === 'success') {
    echo "Payment successful! Transaction ID: " . $response['data']['paymentId'];
} else {
    echo "Error: " . $response['message'];
}
Parameter Details
ParameterTypeDescription
price RequiredfloatThe original total amount of the basket.
paidPrice RequiredfloatThe final amount charged to the customer (including installment differences).
installment OptionalintNumber of installments. Send 1 for a single payment.
card.number RequiredstringCredit card number. 16 digits without spaces.
Edge Case: Basket Total Mismatch
Iyzico strictly requires that the sum of the price values in the items array exactly matches the main price parameter, down to the penny. If there is a mismatch, the API throws a direct error.
3. 3D Secure Payment Flow

The 3D Secure process is a 2-step asynchronous flow. First, a request is made to Iyzico to generate the bank's SMS verification form. After the user verifies, they are caught on the callback URL.

Step 3.1: 3D Secure Initialization (Init)

You only need to append the callbackUrl to the standard pay() parameters.

example.php
<?php
$response = $iyzico->threeDSecureInit([
    // ... the price, card, buyer, and items parameters from the pay() method 
    'callbackUrl' => 'https://yoursite.com/payment/callback'
]);

if ($response['status'] === 'success') {
    // The base64 encrypted HTML form returned by Iyzico is printed to the screen. 
    // The user is automatically redirected to the bank (3D screen).
    echo $response['data']['threeDSHtmlContent'];
    exit;
}
Step 3.2: 3D Callback (Complete)

After the user performs SMS verification at the bank, Iyzico sends a POST request to the callbackUrl you provided.

example.php
<?php
// Route: /payment/callback (POST)
$paymentId = $_POST['paymentId'] ?? null;
$conversationId = $_POST['conversationId'] ?? null;

$response = $iyzico->threeDSecureComplete([
    'paymentId' => $paymentId
]);

if ($response['status'] === 'success') {
    $paymentDetails = $response['data'];
    echo "Payment confirmed! Amount: " . $paymentDetails['paidPrice'];
} else {
    echo "3D Verification failed: " . $response['message'];
}
4. Card Vault (Storing Cards)

Designed to let your users use the "Save My Card" feature. Card data is not stored in your database but on Iyzico's PCI-DSS compliant servers.

Saving a New Card
example.php
<?php
$response = $iyzico->saveCard([
    'holder' => 'Jane Doe',
    'number' => '4546710000000000',
    'month'  => '12',
    'year'   => '2025',
    'alias'  => 'My Business Card'
], '[email protected]'); // The email address is used as the External Identifier.

if ($response['status'] === 'success') {
    // Store these values in the 'user_cards' table in your database
    $cardUserKey = $response['data']['cardUserKey']; // The User's Wallet ID
    $cardToken   = $response['data']['cardToken'];   // The ID of this specific Card
}
To process a payment with a saved card, instead of passing card number etc. into the card array in the regular pay() method, you simply pass the cardUserKey and cardToken parameters you saved. Iyzico will recognize it in the background.
Listing a User's Cards
example.php
<?php
// Send the cardUserKey you fetched from the DB
$response = $iyzico->listCards($cardUserKey);

if ($response['status'] === 'success') {
    foreach ($response['data']['cards'] as $card) {
        echo $card['cardAlias'] . ' : ' . $card['binNumber'] . '***' . $card['lastFourDigits'];
    }
}
5. Cancel & Refund Operations
Canceling the Entire Order (Cancel)

These are transactions performed on the same day before the end of the day (before 23:59). A full refund is issued without commission deductions.

example.php
<?php
$response = $iyzico->cancel('12345678'); // Main PaymentId

if ($response['status'] === 'success') {
    echo "Payment entirely canceled.";
}
Partial / Product-Based Refund

Used after the end of the day has been processed, or to refund a specific item in the basket. It requires the product-based paymentTransactionId instead of the main payment ID.

example.php
<?php
// Refund a single item worth 50 TL from a 100 TL basket
$response = $iyzico->refund('TXN-99887766', 50.0);

if ($response['status'] === 'success') {
    echo "Refund process successful.";
}
6. Marketplace Sub-Merchant

To distribute payments to your sellers (Sub-Merchants), you must register them into the system.

example.php
<?php
$response = $iyzico->createSubMerchant([
    'name'             => 'Ahmet Yılmaz',
    'type'             => 'PERSONAL_COMPANY', // Sole proprietorship
    'legalCompanyName' => 'Ahmet Yılmaz E-Commerce',
    'taxOffice'        => 'Kadıköy',
    'taxNumber'        => '11122233344', // National ID for individuals, Tax Number for companies
    'email'            => '[email protected]',
    'phone'            => '+905551234567',
    'address'          => 'Moda Cad. No:1 Kadikoy / Istanbul',
    'iban'             => 'TR120000000000000000000000',
    'subMerchantExternalId' => 'SELLER-001' // Vendor ID in your own DB
]);

if ($response['status'] === 'success') {
    // Save this key in the database for the vendor.
    // You will use it as 'subMerchantKey' and 'subMerchantPrice' in the basket items structure.
    $subMerchantKey = $response['data']['subMerchantKey'];
}