avangard / api
AVANGARD API v4 客户端 for php
Requires
- php: >=5.6.0
- ext-curl: *
- ext-dom: *
- ext-json: *
- ext-mbstring: *
- ext-openssl: *
- guzzlehttp/guzzle: ^6.4
- psr/http-message: 1.0.1 as 1.0
- psr/log: ^1.0.2
README
用于与银行 Avangard 的 API V4 集成的库。实现了对银行 API 的主要请求。请参阅技术文档以了解 API 的详细说明。
使用 composer 安装
- 在您打算安装库的目录下,创建一个包含以下内容的 composer.json 文件
{ "require": { "avangard/api": "dev-master" }, "repositories": [ { "type": "git", "url": "https://github.com/avangardDeveloper/Avangard-PHP-Lib" } ] }
- 在同一个目录下执行以下命令
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。此方法从网站中发送错误报告。
订单和支付
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>
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); } }
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); } }
来自银行的回调请求
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); } }
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); } }
退款和取消支付
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); } }
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); } }
订单操作
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); } }
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
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')
要准备发送到在线收银机的检查,必须填写有关公司、检查中的每个项目和购买总金额的数据。
将检查发送到在线收银机
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); } }
refundBill($data)
- 向在线收银机发送退款检查
参数
ReceiptEntity $data
- 准备好的用于发送到在线收银机的检查
使用方法与sendBill($data)
类似。