AVANGARD API v4 客户端 for php

3.1.0 2024-08-22 08:22 UTC

README

用于与银行 Avangard 的 API V4 集成的库。实现了对银行 API 的主要请求。请参阅技术文档以了解 API 的详细说明。

使用 composer 安装

  1. 在您打算安装库的目录下,创建一个包含以下内容的 composer.json 文件
{
    "require": {
        "avangard/api": "dev-master"
    },
    "repositories": [
        {
            "type": "git",
            "url": "https://github.com/avangardDeveloper/Avangard-PHP-Lib"
        }
    ]
}
  1. 在同一个目录下执行以下命令
composer install

使用

将库连接到项目中

要使用库中的方法,需要在您的代码中连接类自动加载脚本并创建一个 ApiClient 类的对象。

require_once ("vendor/autoload.php");
use Avangard\ApiClient;

$apiClient = new ApiClient($shopId, $shopPassword, $shopSign, $serverSign, $boxAuth, $proxy);

构造函数参数

  • shopId - 银行系统中互联网商店的 ID*
  • shopPassword - 银行系统中互联网商店的密码*
  • shopSign - 银行系统中互联网商店的签名*
  • serverSign - 银行签名的响应*
  • boxAuth - 包含用于向在线收银机发送检查的授权数据的对象。如果传递 null,则不会发送检查。有关详细信息,请参阅 此处
  • proxy - 如果使用,则指定 http url 代理服务器。默认为 null

*这些参数在签订互联网支付合同时由银行技术支持提供

注意!
应使用 try/catch 构造使用本库的所有方法

try {
    // All methods here...
} catch (\Exception $e) {
    if ($debug) {
        \Avangard\Lib\Logger::log($e);
        // Your custom logging here...
    }
}

建议使用带有 $debug 标志的 \Avangard\Lib\Logger::log 方法,该标志可以设置在网站的行政面板中。此方法将错误报告发送到开发者的telegram。此方法从网站中发送错误报告。

订单和支付

  1. prepareForms($order, $type) - 准备支付表单的参数。

参数

  •   $order = [
          'AMOUNT' => 'number, обязательный',                     // сумма к оплате в копейках
          'ORDER_NUMBER' =>  'string, обязательный',              // номер заказа в интернет-магазине
          'ORDER_DESCRIPTION' => 'string, обязательный',          // описание заказа в интернет-магазине
          'LANGUAGE' => 'string, обязательный, по умолчанию RU',  // язык описания заказа в интернет-магазине
          'BACK_URL' => 'string, обязательный',                   // ссылка безусловного редиректа
          'BACK_URL_OK' => 'string',                              // ссылка успешного редиректа
          'BACK_URL_FAIL' => 'string',                            // ссылка НЕуспешного редиректа
          'CLIENT_NAME' => 'string',                              // имя плательщика
          'CLIENT_ADDRESS' => 'string',                           // физический адрес плательщика
          'CLIENT_EMAIL' => 'string',                             // email плательщика
          'CLIENT_PHONE' => 'string',                             // телефон плательщика
          'CLIENT_IP' => 'string'                                 // ip-адрес плательщика  
      ];
  •   $type =
          ApiClient::HOST2HOST    // Регистрирует оплату в интернет-эквайринге и возвращает TICKET-параметр для последующей оплаты заказа
          ApiClient::POSTFORM     // Подготавливает параметры для HTML формы оплаты, показываемой на стороне клиента (часто требуется для CMS)
          ApiClient::GETURL       // Регистрирует оплату в интернет-эквайринге и возвращает ссылку для последующей оплаты заказа

返回值

  • $type = ApiClient::HOST2HOST:
[
    "URL" => "https://pay.avangard.ru/iacq/pay",
    "METHOD" => "get",
    "INPUTS" => [
        "TICKET" => "JGceLCtt000012682687LskJXuIpbfmpgeeKgkcj"
    ]
]
  • $type = ApiClient::POSTFORM:
[
  "URL" => "https://pay.avangard.ru/iacq/post",
  "METHOD" => "post",
  "INPUTS" => [
    "SHOP_ID" => "1",
    "SHOP_PASSWD" => "pass",
    "AMOUNT" => 1000,
    "ORDER_NUMBER" => "sa12",
    "ORDER_DESCRIPTION" => "My desc",
    "BACK_URL" => "http://example.ru/payments/avangard/?result=success",
    "LANGUAGE" => "RU",
    "SIGNATURE" => "1EBE4761D9B165D8FF784803686AF511",
  ]
]
  • $type = ApiClient::GETURL:
"https://pay.avangard.ru/iacq/pay?ticket=JGceLCtt000012682687LskJXuIpbfmpgeeKgkcj"

HOST2HOST/GETURL 示例

<?php
require_once "vendor/autoload.php";
use Avangard\ApiClient;

$debug = true;

try {
    $apiClient = new ApiClient(
        1,
        'shop password',
        'shop sign',
        'server sign',
        null
    );
    
    $order = [
        'AMOUNT' => 1000,
        'ORDER_NUMBER' => 'sa12',
        'ORDER_DESCRIPTION' => 'My desc',
        'BACK_URL' => 'http://example.ru/payments/avangard/?result=success'
    ];
    
    $result = $apiClient->request->prepareForms($order, ApiClient::HOST2HOST);
    
    print_r($result);
} catch (\Exception $e) {
    if ($debug) {
        \Avangard\Lib\Logger::log($e);
    }
}

POSTFORM 示例

<?php
require_once "vendor/autoload.php";

use Avangard\ApiClient;

function getFormData($orderNumber, $orderDescription, $amount)
{
    $debug = true;
    
    try {
        $apiClient = new ApiClient(
            1,
            'shop password',
            'shop sign',
            'server sign',
            null
        );
        
        $order = [
            'AMOUNT' => $amount,
            'ORDER_NUMBER' => $orderNumber,
            'ORDER_DESCRIPTION' => $orderDescription,
            'BACK_URL' => 'http://example.ru/payments/avangard/?result=success'
        ];
        
        $result = $apiClient->request->prepareForms($order, ApiClient::POSTFORM);
        
        return $result;
    } catch (\Exception $e) {
        if ($debug) {
            \Avangard\Lib\Logger::log($e);
        }
    }
}

$orderNumber = 'sa12';
$orderDescription = 'My desc';
$amount = 1000;

$formData = getFormData($orderNumber, $orderDescription, $amount);
?>

<form id="form" action="<?=$formData['URL'];?>" method="<?=$formData['METHOD'];?>">
    <?php foreach ($formData['INPUTS'] as $name => $value):?>
        <input type="hidden" name="<?=$name;?>" value="<?=$value;?>">
    <?php endforeach;?>
    <button type="submit">Перейти к оплате</button>
</form>
  1. orderRegister($order) - 在互联网支付中注册支付并返回用于进一步支付的 TICKET 参数。

参数

$order = [
    'AMOUNT' => 'number, обязательный',                     // сумма к оплате в копейках
    'ORDER_NUMBER' =>  'string, обязательный',              // номер заказа в интернет-магазине
    'ORDER_DESCRIPTION' => 'string, обязательный',          // описание заказа в интернет-магазине
    'LANGUAGE' => 'string, обязательный, по умолчанию RU',  // язык описания заказа в интернет-магазине
    'BACK_URL' => 'string, обязательный',                   // ссылка безусловного редиректа
    'BACK_URL_OK' => 'string',                              // ссылка успешного редиректа
    'BACK_URL_FAIL' => 'string',                            // ссылка НЕуспешного редиректа
    'CLIENT_NAME' => 'string',                              // имя плательщика
    'CLIENT_ADDRESS' => 'string',                           // физический адрес плательщика
    'CLIENT_EMAIL' => 'string',                             // email плательщика
    'CLIENT_PHONE' => 'string',                             // телефон плательщика
    'CLIENT_IP' => 'string'                                 // ip-адрес плательщика  
];

返回值

[
  "TICKET" => "xQElJQhi000012682701rKuBUpngKsIsUBKPBmfM"
]

示例

<?php
require_once "vendor/autoload.php";
use Avangard\ApiClient;

$debug = true;
    
try {
    $apiClient = new ApiClient(
        1,
        'shop password',
        'shop sign',
        'server sign',
        null
    );
    
    $order = [
        'AMOUNT' => 1000,
        'ORDER_NUMBER' => 'sa12',
        'ORDER_DESCRIPTION' => 'My desc',
        'BACK_URL' => 'http://example.ru/payments/avangard/?result=success'
    ];
    
    $result = $apiClient->request->orderRegister($order);
    
    print_r($result);
} catch (\Exception $e) {
    if ($debug) {
        \Avangard\Lib\Logger::log($e);
    }
}
  1. getOrderByTicket($ticket) - 根据TICKET参数获取支付信息。

参数

  • string $ticket - 银行互联网支付系统中支付的唯一标识符

返回示例数组

[
    'id' => 1234567890,
    'method_name' => 'SCR',
    'auth_code' => 'ABC123',
    'status_code' => 5,
    'status_desc' => 'Авторизация успешно завершена',
    'status_date' => '2012-04-23T12:47:00+04:00',
]

示例

<?php
require_once "vendor/autoload.php";
use Avangard\ApiClient;

$debug = true;
    
try {
    $apiClient = new ApiClient(
        1,
        'shop password',
        'shop sign',
        'server sign',
        null
    );
    
    $result = $apiClient->request->getOrderByTicket("UWyNLGVh000012669958czZpckkboKNDpUysDhlL");
    
    print_r($result);
} catch (\Exception $e) {
    if ($debug) {
        \Avangard\Lib\Logger::log($e);
    }
}

来自银行的回调请求

  1. isCorrectHash($params) - 检查来自银行的回调请求的签名。

参数

  • array $params - 请求的输入参数数组

返回值
如果签名正确,则返回 true,否则返回 false

示例

<?php
require_once "vendor/autoload.php";
use Avangard\ApiClient;

$debug = true;

$_REQUEST = [
    'id' => '12663423',
    'signature' => '07EB5673A9ECD4506C112B3EE3E3AF80',
    'method_name' => 'D3S',
    'shop_id' => '1',
    'ticket' => 'OWXZAkWg000012663423irlhpRKbAevpPsymgoDu',
    'status_code' => '3',
    'auth_code' => '',
    'amount' => '2000',
    'card_num' => '546938******1152',
    'order_number' => 'sa12',
    'status_desc' => 'Исполнен',
    'status_date' => '2019-11-05 10:17:17.0',
    'refund_amount' => '0',
    'exp_mm' => '09',
    'exp_yy' => '22'
];

try {
    $apiClient = new ApiClient(
        1,
        'shop password',
        'shop sign',
        'server sign',
        null
    );
    
    $result = $apiClient->request->isCorrectHash($_REQUEST);
    
    var_dump($result); // true или false
} catch (\Exception $e) {
    if ($debug) {
        \Avangard\Lib\Logger::log($e);
    }
}
  1. sendResponse() - 向银行的回调请求发送正确的状态代码响应,然后结束脚本执行。如果您实现处理银行的回调请求,请在处理成功后始终调用此方法

示例

<?php
require_once "vendor/autoload.php";
use Avangard\ApiClient;

$debug = true;

$_REQUEST = array (
    'id' => '12663423',
    'signature' => '07EB5673A9ECD4506C112B3EE3E3AF80',
    'method_name' => 'D3S',
    'shop_id' => '1',
    'ticket' => 'OWXZAkWg000012663423irlhpRKbAevpPsymgoDu',
    'status_code' => '3',
    'auth_code' => '',
    'amount' => '200',
    'card_num' => '546938******1152',
    'order_number' => 'sa12',
    'status_desc' => 'Исполнен',
    'status_date' => '2019-11-05 10:17:17.0',
    'refund_amount' => '0',
    'exp_mm' => '09',
    'exp_yy' => '22'
);

try {
    $apiClient = new ApiClient(
        1,
        'shop password',
        'shop sign',
        'server sign',
        null
    );
    
    if ($apiClient->request->isCorrectHash($_REQUEST)) {
    
        // Действия при получении callback запроса из банка...
    
        // Отправляем ответ, что callback запрос был успешно обработан
        $apiClient->request->sendResponse();
    }
} catch (\Exception $e) {
    if ($debug) {
        \Avangard\Lib\Logger::log($e);
    }
}

退款和取消支付

  1. orderRefund($ticket, $amount = null) - 根据特定支付进行部分/全部退款。
    如果支付是通过 QR 码(通过SBP)完成的,则在发送退款请求后,方法将检查退款的状态,因为通过 QR 码进行的支付是异步进行的。总共进行最多 8 次状态检查,每次检查之间延迟 5 秒

参数

  • string $ticket - 银行互联网支付系统中支付的唯一标识符
  • number $amount - 退款金额(以分为单位)。如果不传递此参数,则将进行全部退款

返回值

[
    "transaction_id" => 124665
]

示例

<?php
require_once "vendor/autoload.php";
use Avangard\ApiClient;

$debug = true;

try {
    $apiClient = new ApiClient(
        1,
        'shop password',
        'shop sign',
        'server sign',
        null
    );

    $result = $apiClient->request->orderRefund("UWyNLGVh000012669958czZpckkboKNDpUysDhlL", 10000);
    
    print_r($result);
} catch (\Exception $e) {
    if ($debug) {
        \Avangard\Lib\Logger::log($e);
    }
}
  1. orderCancel($ticket) - 取消先前注册但尚未付款的支付尝试。如果需要以某种原因禁止用户通过订单付款,则需要调用此方法。

参数

  • string $ticket - 银行互联网支付系统中支付的唯一标识符

返回值
如果支付已取消,则返回 true

示例

<?php
require_once "vendor/autoload.php";
use Avangard\ApiClient;

$debug = true;

try {
    $apiClient = new ApiClient(
        1,
        'shop password',
        'shop sign',
        'server sign',
        null
    );
    
    $order = [
        'AMOUNT' => 1000,
        'ORDER_NUMBER' => 'sa12',
        'ORDER_DESCRIPTION' => 'My desc',
        'BACK_URL' => 'http://example.ru/payments/avangard/?result=success'
    ];
    
    $registerResult = $apiClient->request->orderRegister($order);

    $cancelResult = $apiClient->request->orderCancel($registerResult['TICKET']);
    
    var_dump($cancelResult);
} catch (\Exception $e) {
    if ($debug) {
        \Avangard\Lib\Logger::log($e);
    }
}

订单操作

  1. getOpersByOrderNumber($order_number) - 通过订单号获取在线商店的操作列表。

参数

  • string $order_number - 在线商店的订单号

返回示例数组

[
    [
        'id' => 1054751,
        'ticket' => '1234567890ABCDEABCDE12345678901234567890',
        'order_number' => '1',
        'status_code' => 1,
        'status_desc' => 'Обрабатывается',
        'status_date' => '2013-08-14T10:23:49+04:00',
        'amount' => 10000.0,
    ],
    [
        'id' => 1054752,
        'ticket' => '1234567890ABCDEABCDE12345678901234567811',
        'order_number' => '1',
        'status_code' => 1,
        'status_desc' => 'Обрабатывается',
        'status_date' => '2013-08-14T10:24:00+04:00',
        'amount' => 10000.0,
    ],
    [
        'id' => 1054753,
        'ticket' => '1234567890ABCDEABCDE12345678901234567822',
        'order_number' => '1',
        'method_name' => 'CVV',
        'status_code' => 2,
        'status_desc' => 'Отбракован',
        'status_date' => '2013-08-14T10:27:17+04:00',
        'amount' => 10000.0,
        'refund_amount' => 10000.0,
        'card_num' => '411111******1111',
        'exp_mm' => 12,
        'exp_yy' => 15,
    ]
]

示例

<?php
require_once "vendor/autoload.php";
use Avangard\ApiClient;

$debug = true;

try {
    $apiClient = new ApiClient(
        1,
        'shop password',
        'shop sign',
        'server sign',
        null
    );

    $result = $new->request->getOpersByOrderNumber("sa12");
    
    print_r($result);
} catch (\Exception $e) {
    if ($debug) {
         \Avangard\Lib\Logger::log($e);
     }
}
  1. getOpersByDate($date) - 获取特定日期的操作列表。

参数

  • string $date - 日期

返回值
返回的数组与getOpersByOrderNumber方法完全相同

示例

<?php
require_once "vendor/autoload.php";
use Avangard\ApiClient;

$debug = true;

try {
    $apiClient = new ApiClient(
        1,
        'shop password',
        'shop sign',
        'server sign',
        null
    );

    $result = $apiClient->request->getOpersByDate("2019-11-06");
    
    print_r($result);
} catch (\Exception $e) {
    if ($debug) {
         \Avangard\Lib\Logger::log($e);
     }
}

发送检查到在线收银机

该库允许将检查发送到在线收银机。目前已实现与АТОЛ Онлайн ФФД 1.05、АТОЛ Онлайн ФФД 1.2和OrangeData的集成。

生成收银机授权数据

应将连接到在线收银机的配置存储在数据库中,格式为JSON字符串。要创建有效的JSON,您可以使用包含在本库中的收银机授权数据生成器。它位于路径vendor/avangard/api/src/generateBoxAuth/index.php

  1. BoxAuthFactory::createBoxAuth($boxJson) - 返回包含收银机$boxAuth授权数据的对象,以便将其传递到ApiClient类构造函数中

参数

  • $boxJson - 收银机授权数据的JSON对象

返回值
根据所选收银机

  • AtolonlineV4 用于 АТОЛ Онлайн ФФД 1.05;
  • AtolonlineV5 用于 АТОЛ Онлайн ФФД 1.2;
  • Orangedata 用于 OrangeData;
  • null,如果未选择收银机或不存在收银机;

示例

<?php
require_once "vendor/autoload.php";
use Avangard\ApiClient;
use Avangard\Lib\Box\BoxAuthFactory;

$debug = true;

try {
    $boxJson = $db->getBoxJson(); // Ваш метод получения JSON строки с авторизационными данными для кассы
    $boxAuth = BoxAuthFactory::createBoxAuth($boxJson);

    $apiClient = new ApiClient(
        1,
        'shop password',
        'shop sign',
        'server sign',
        $boxAuth
    );
    
    var_dump($apiClient->request->isBox()); // true, в случае успешного подключения к кассе
} catch (\Exception $e) {
    if ($debug) {
         \Avangard\Lib\Logger::log($e);
     }
}

注意!
如果使用非null$boxAuth参数创建了ApiCLient对象,则会在类构造函数中尝试连接到收银机。如果无法连接到收银机,则会抛出Exception,并且脚本的工作将停止

为发送到在线收银机的检查做准备

发送到在线收银机的检查表示为ReceiptEntity类的对象

$receipt = new ReceiptEntity($id, $time);

构造函数参数

  • string $id - 在线商店的订单号
  • int $time - 当前时间戳

类中的其他参数

  • ClientEntity $client - 包含买家信息的对象
  • ReceiptItemEntity[] $items - 包含检查中每个项目信息的对象数组
  • float $total - 包括配送在内的购买总金额

买家信息以ClientEntity类的对象形式表示

$client = new ClientEntity($name);

构造函数参数

  • string $name - 买家的姓名

类中的其他参数

  • string $phone - 买家的电话
  • string $email - 买家的电子邮件

检查中的项目信息以ReceiptItemEntity类的对象形式表示

$receiptItem = new ReceiptItemEntity($name, $price, $quantity, $sum);

构造函数参数

  • string $name - 商品名称
  • float $price - 商品价格
  • float $quantity - 商品数量
  • float $sum - 商品总成本(通常是数量*价格)

类中的其他参数

  • string $payment_object - 计算对象

要向检查中添加配送,请使用ReceiptItemEntity::delivery方法

$deliveryReceiptItem = ReceiptItemEntity::delivery($name, $price, $quantity, $sum);

方法参数与ReceiptItemEntity构造函数中使用的参数类似。此方法的区别在于其中设置了$payment_object = 'service',这对应于计算对象"服务"。

默认情况下,每个检查项的计算对象从包含授权数据的JSON对象中获取,但如果需要向检查中添加具有不同计算对象的项,则在创建ReceiptItemEntity对象后调用方法setPaymentObject($paymentObject)并传递在线收银机文档要求的字符串值对象计算对象

$receiptItem = new ReceiptItemEntity($name, $price, $quantity, $sum);

$receiptItem->setPaymentObject('commodity')

要准备发送到在线收银机的检查,必须填写有关公司、检查中的每个项目和购买总金额的数据。

将检查发送到在线收银机

  1. sendBill($data) - 向在线收银机发送购买检查

参数

  • ReceiptEntity $data - 准备好的用于发送到在线收银机的检查

示例

<?php
require_once "vendor/autoload.php";
use Avangard\ApiClient;
use Avangard\Lib\Box\BoxAuthFactory;
use Box\DataObjects\ClientEntity;
use Box\DataObjects\ReceiptEntity;
use Box\DataObjects\ReceiptItemEntity;

$debug = true;

try {
    $boxJson = $db->getBoxJson(); // Ваш метод получения JSON строки с авторизационными данными для кассы
    $boxAuth = BoxAuthFactory::createBoxAuth($boxJson);

    $apiClient = new ApiClient(
        1,
        'shop password',
        'shop sign',
        'server sign',
        $boxAuth
    );
    
    // Перед отправкой чека необходимо проверять, есть ли подключение к кассе 
    if ($apiClient->request->isBox()) {
        $orderData = $_REQUEST['order'];
        
        // Создаём чек с номером заказа и текущим временем
        $receipt = new ReceiptEntity((string)$orderData['id'], time());
        
        // Создаём и заполняем объект данных о покупателе
        $client = new ClientEntity($orderData['client_firstname'] . ' ' . $orderData['client_lastname']);
        
        // Одно из двух полей phone или email должно быть обязательно заполнено
        $client->setPhone($order['phone']);
        $client->setEmail($order['email']);
        
        // Добавляем данные о покупателе в чек 
        $receipt->addClient($client);

        // Добавляем общую сумму заказа в чек
        $receipt->addTotal($order['total']);

        // Заполняем позиции в чеке
        foreach ($orderData['items'] as $product) {
            $receipt->addReceiptItem(
                new ReceiptItemEntity(
                    $product['name'],
                    $product['price'],
                    $product['quantity'],
                    $product['total']
                )
            );
        }

        // Если есть платная доставка, добавляем её в чек
        if (!empty($orderData['delivery'])) {
            $receipt->addReceiptItem(
                ReceiptItemEntity::delivery(
                    $orderData['delivery']['name'],
                    round($orderData['delivery']['price']),
                    1,
                    round($orderData['delivery']['price'])
                )
            );
        }

        // Отправляем чек в кассу
        $this->client->request->sendBill($receipt);
    }
} catch (\Exception $e) {
    if ($debug) {
         \Avangard\Lib\Logger::log($e);
     }
}
  1. refundBill($data) - 向在线收银机发送退款检查

参数

  • ReceiptEntity $data - 准备好的用于发送到在线收银机的检查

使用方法与sendBill($data)类似。