Создание модуля оплаты Bitcoin в OpenCart: часть 2
29 Мая 2022г. в 05:07Контроллер
Перейдите в catalog/controller/payment
Создайте файл PHP файл bitpay.php
Откройте этот файл в вашей IDE и напишите класс этого модуля, придерживаясь способа именования OpenCart, например, class ControllerPaymentBitpay extends Controller {}
Внутри класса создайте стандартную OpenCart функцию index
Внутри функции index() напишите код ниже
Загрузка языков и парсинг значений
Первая строка кода ниже загружает язык в контроллер, следующие строки парсят ссылки и тексты на языке для использования в представлении.
$this->language->load('payment/bitpay');
$this->data['button_bitpay_confirm'] = $this->language->get('text_button_confirm');
$this->data['continue']= $this->url->link('checkout/success');
$this->language->load('payment/bitpay');
$this->data['button_bitpay_confirm'] = $this->language->get('text_button_confirm');
$this->data['continue']= $this->url->link('checkout/success');
Шаблон и рендеринг
Чтобы указать путь к шаблону:
$this->template = $this->config->get('config_template') . '/template/payment/bitpay.tpl';
$this->template = $this->config->get('config_template') . '/template/payment/bitpay.tpl';
Чтобы отрендерить шаблон: $this->render();.
Функция запроса в API
До настоящего времени мы писали только код, относящийся к настройкам модуля и его макета. Сейчас мы перейдем к связи с API. Для этого мы создадим другую функцию внутри нашего контроллера, которая будет общаться с BitPay API. Мы создадим public function send(){}. Код внутри этой функции ниже объясняется построчно:
Загрузка необходимых библиотек/классов в контроллер
Нам необходимо загрузить в наш контроллер 2 обязательных класса/библиотеки — BitPay Library API и Order Model:
include DIR_APPLICATION.'../bitpay/bp_lib.php';
$this->load->model('checkout/order');
include DIR_APPLICATION.'../bitpay/bp_lib.php';
$this->load->model('checkout/order');
(BitPay Library не библиотека OpenCart, поэтому мы напрямую вставим ее функции в наш контроллер, как показано на первой строчке сверху)
Получение деталей заказа и форматирование
Чтобы получить все детали заказа, можно использовать:
$order = $this->model_checkout_order->getOrder($this->session->data['order_id']);
$order = $this->model_checkout_order->getOrder($this->session->data['order_id']);
В переменную падают все необходимые детали в форме массива. Для форматирования стандартной выбранной валюты заказа мы используем:
$price = $this->currency->format($order['total'], $order['currency_code'], $order['currency_value'], false);
$price = $this->currency->format($order['total'], $order['currency_code'], $order['currency_value'], false);
Взаимодействие с API
Следующий код взаимодействует с API и парсит обязательные данные в функцию API.
$posData = $order['order_id']; // Order Information to be posted in the API
$options = array(
'apiKey' => $this->config->get('bitpay_api_key'), // API Key fetched from database
'notificationURL' => $this->url->link('payment/bitpay/callback'), // The API callback URL
'redirectURL' => $this->url->link('account/order/info&order_id=' . $order['order_id']), // Order Information URL
'currency' => $order['currency_code'], // Ordered Currency Code
'transactionSpeed' => $this->config->get('bitpay_transaction_speed'), // Transaction Speed (See the API Documentation for detail)
'testMode' => $this->config->get('bitpay_test_mode') // Set Test Mode enabled or disabled
);
$response = bpCreateInvoice($order['order_id'], $price, $posData, $options); // Parse the Information to API
$posData = $order['order_id']; // Order Information to be posted in the API
$options = array(
'apiKey' => $this->config->get('bitpay_api_key'), // API Key fetched from database
'notificationURL' => $this->url->link('payment/bitpay/callback'), // The API callback URL
'redirectURL' => $this->url->link('account/order/info&order_id=' . $order['order_id']), // Order Information URL
'currency' => $order['currency_code'], // Ordered Currency Code
'transactionSpeed' => $this->config->get('bitpay_transaction_speed'), // Transaction Speed (See the API Documentation for detail)
'testMode' => $this->config->get('bitpay_test_mode') // Set Test Mode enabled or disabled
);
$response = bpCreateInvoice($order['order_id'], $price, $posData, $options); // Parse the Information to API
Обработка ошибок
По некоторым невалидным действиям API выбрасывает ошибку пользователю. Следующий код бросает ответ нам в формате JSON:
if(array_key_exists('error', $response){ echo "{\"error\": \"Error: Problem communicating with payment provider.\\nPlease try again later.\"}";}
else{echo "{\"url\": \"" . $response["url"] . "\"}"; }
if(array_key_exists('error', $response){ echo "{\"error\": \"Error: Problem communicating with payment provider.\\nPlease try again later.\"}";}
else{echo "{\"url\": \"" . $response["url"] . "\"}"; }
Колбек функция
По заголовку должно быть понятно, что это будет колбек функция API. Она возвращает необходимую информацию о способе оплаты и передает ее пользователю. Выполните следующие шаги:
Создайте публичную функцию callback()
Внутри функции подключите библиотеку DIR_APPLICATION.’../bitpay/bp_lib.php’;
Получите API Response Array Key с помощью следующего кода
$apiKey = $this->config->get('bitpay_api_key');
$response = bpVerifyNotification($apiKey);
$apiKey = $this->config->get('bitpay_api_key');
$response = bpVerifyNotification($apiKey);
Проверьте ответ. Если это строка, то должна быть ошибка:
if (is_string($response))
{
// Display the response error code here
}
if (is_string($response))
{
// Display the response error code here
}
Внутри выражения else необходимо подтвердить заказ с помощью кода ниже.
switch($response['status'])
{
// If Order is successful and complete
case 'confirmed':
case 'complete':
$this->load->model('checkout/order'); // Loading the Order Model
$order_id = $response['posData']; // Getting the Order ID from the response
$order = $this->model_checkout_order->getOrder($order_id); // Get Order Details
$this->model_checkout_order->confirm($order_id, $this->config->get('bitpay_confirmed_status_id')); // Confirm the Order Status as complete
break;
case 'invalid': // If Order is invalid due to some problems
$this->load->model('checkout/order'); // loading the Order Model
$order_id = $response['posData']; // Getting the Order ID from the response
$order = $this->model_checkout_order->getOrder($order_id); // Get Order Details
$this->model_checkout_order->confirm($order_id, $this->config->get('bitpay_invalid_status_id')); // Confirm the Order Status as Invalid
break;
}
switch($response['status'])
{
// If Order is successful and complete
case 'confirmed':
case 'complete':
$this->load->model('checkout/order'); // Loading the Order Model
$order_id = $response['posData']; // Getting the Order ID from the response
$order = $this->model_checkout_order->getOrder($order_id); // Get Order Details
$this->model_checkout_order->confirm($order_id, $this->config->get('bitpay_confirmed_status_id')); // Confirm the Order Status as complete
break;
case 'invalid': // If Order is invalid due to some problems
$this->load->model('checkout/order'); // loading the Order Model
$order_id = $response['posData']; // Getting the Order ID from the response
$order = $this->model_checkout_order->getOrder($order_id); // Get Order Details
$this->model_checkout_order->confirm($order_id, $this->config->get('bitpay_invalid_status_id')); // Confirm the Order Status as Invalid
break;
}
Представление
Созданное представление довольно простое. Всего лишь одна кнопка с AJAX запросом к API:
<div class="buttons">
<div class="right"><a id="confirm-btn" class="button"><span><?php echo $button_bitpay_confirm; ?></span></a></div>
</div>
<script type="text/javascript"><!--
$('#confirm-btn').bind('click', function() {
$.ajax({
type: 'GET',
url: 'index.php?route=payment/bitpay/send',
timeout: (1000 * 30), // 30 seconds
error: function() {
alert('Error communication.');
},
success: function(msg) {
try {
var result = JSON.parse(msg);
if(result.error) {
alert(result.error);
} else {
location = result.url;
}
} catch(e) {
alert('JSON parsing error: '+msg);
}
}
});
});
//--></script>
<div class="buttons">
<div class="right"><a id="confirm-btn" class="button"><span><?php echo $button_bitpay_confirm; ?></span></a></div>
</div>
<script type="text/javascript"><!--
$('#confirm-btn').bind('click', function() {
$.ajax({
type: 'GET',
url: 'index.php?route=payment/bitpay/send',
timeout: (1000 * 30), // 30 seconds
error: function() {
alert('Error communication.');
},
success: function(msg) {
try {
var result = JSON.parse(msg);
if(result.error) {
alert(result.error);
} else {
location = result.url;
}
} catch(e) {
alert('JSON parsing error: '+msg);
}
}
});
});
//--></script>
Заключение
Эта серия должна познакомить вас с созданием более сложных модулей в OpenCart. Теперь чтобы продолжить делать этот плагин, вам необходимо открыть документацию OpenCart.