Skip to content

Commit

Permalink
First version add
Browse files Browse the repository at this point in the history
  • Loading branch information
plisdeveloper committed Aug 16, 2022
0 parents commit c925cb3
Show file tree
Hide file tree
Showing 5 changed files with 388 additions and 0 deletions.
7 changes: 7 additions & 0 deletions includes/languages/english/modules/payment/plisio.php
@@ -0,0 +1,7 @@
<?php

define('MODULE_PAYMENT_PLISIO_TEXT_TITLE', 'Plisio Payment Gateway');
define('MODULE_PAYMENT_PLISIO_TEXT_DESCRIPTION', 'Plisio is a payment gateway for Bitcoin, Litecoin, Ethereum and 30 other cryptocurrencies. With our API, any website can accept crypto payments.');
define('MODULE_PAYMENT_PLISIO_TEXT_EMAIL_FOOTER', 'You have attempted to make an order using Plisio!');
define('MODULE_PAYMENT_PLISIO_CREATE_INVOICE_FAILED', 'Unable to process payment using Plisio.');
define('MODULE_PAYMENT_PLISIO_ORDER_ERROR_TITLE', 'There has been an error processing your order');
151 changes: 151 additions & 0 deletions includes/modules/payment/Plisio/Lib/PlisioClient.php
@@ -0,0 +1,151 @@
<?php

namespace PlisioClient;

class PlisioClient
{
protected $secretKey = '';
public $apiEndPoint = 'https://plisio.net/api/v1';


public function __construct($secretKey)
{
$this->secretKey = $secretKey;
}

protected function getApiUrl($commandUrl)
{
return trim($this->apiEndPoint, '/') . '/' . $commandUrl;
}

public function getBalances($currency)
{
return $this->apiCall('balances', array('currency' => $currency));
}

public function getCurrencies($source_currency = 'USD')
{
$currencies = $this->guestApiCall("currencies/$source_currency");
return array_filter($currencies['data'], function ($currency) {
return $currency['hidden'] == 0;
});
}

public function createTransaction($req)
{
return $this->apiCall('invoices/new', $req);
}


/**
* Creates a withdrawal from your account to a specified address.<br />
* @param amount The amount of the transaction (floating point to 8 decimals).
* @param currency The cryptocurrency to withdraw.
* @param address The address to send the coins to.
* @param auto_confirm If auto_confirm is TRUE, then the withdrawal will be performed without an email confirmation.
*/
public function createWithdrawal($amount, $currency, $address)
{
$req = array(
'currency' => $currency,
'amount' => $amount,
'to' => $address,
'type' => 'cash_out',
);
return $this->apiCall('operations/withdraw', $req);
}

/**
* Creates a withdrawal from your account to a specified address.<br />
* @param payments array of addresses and amounts.
* @param currency The cryptocurrency to withdraw.
*/
public function createMassWithdrawal($payments, $currency)
{
$req = array(
'currency' => $currency,
'amount' => implode(',', array_values($payments)),
'to' => implode(',', array_keys($payments)),
'type' => 'mass_cash_out',
);
return $this->apiCall('operations/withdraw', $req);
}


private function isSetup()
{
return !empty($this->secretKey);
}

protected function getCurlOptions($url)
{
return [
CURLOPT_URL => $url,
CURLOPT_HTTPGET => true,
CURLOPT_FAILONERROR => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HEADER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Accept: application/json'
],
];
}

private function apiCall($cmd, $req = array())
{
if (!$this->isSetup()) {
return array('error' => 'You have not called the Setup function with your private and public keys!');
}
return $this->guestApiCall($cmd, $req);
}

private function guestApiCall($cmd, $req = array())
{
// Generate the query string
$queryString = '';
if (!empty($this->secretKey)) {
$req['api_key'] = $this->secretKey;
}
if (!empty($req)) {
$post_data = http_build_query($req, '', '&');
$queryString = '?' . $post_data;
}

try {
$apiUrl = $this->getApiUrl($cmd . $queryString);

$ch = curl_init();
curl_setopt_array($ch, $this->getCurlOptions($apiUrl));
$data = curl_exec($ch);

if ($data !== FALSE) {
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$body = substr($data, $header_size);
$dec = $this->jsonDecode($body);
if ($dec !== NULL && count($dec)) {
return $dec;
} else {
// If you are using PHP 5.5.0 or higher you can use json_last_error_msg() for a better error message
return array('status' => 'error', 'message' => 'Unable to parse JSON result (' . json_last_error() . ')');
}
} else {
return array('status' => 'error', 'message' => 'cURL error: ' . curl_error($ch));
}
} catch (\Exception $e) {
return array('status' => 'error', 'message' => 'Could not send request to API : ' . $apiUrl);
}
}

private function jsonDecode($data)
{
if (PHP_INT_SIZE < 8 && version_compare(PHP_VERSION, '5.4.0') >= 0) {
// We are on 32-bit PHP, so use the bigint as string option. If you are using any API calls with Satoshis it is highly NOT recommended to use 32-bit PHP
$dec = json_decode($data, TRUE, 512, JSON_BIGINT_AS_STRING);
} else {
$dec = json_decode($data, TRUE);
}
return $dec;
}
}
3 changes: 3 additions & 0 deletions includes/modules/payment/Plisio/version.php
@@ -0,0 +1,3 @@
<?php

define('PLISIO_ZENCART_EXTENSION_VERSION', '1.0.0');
164 changes: 164 additions & 0 deletions includes/modules/payment/plisio.php
@@ -0,0 +1,164 @@
<?php

class plisio extends base
{
public $code;
public $title;
public $description;
public $enabled;

function __construct()
{
$this->code = 'plisio';
$this->title = MODULE_PAYMENT_PLISIO_TEXT_TITLE;
$this->description = MODULE_PAYMENT_PLISIO_TEXT_DESCRIPTION;
$this->api_key = MODULE_PAYMENT_PLISIO_API_KEY;
$this->sort_order = MODULE_PAYMENT_PLISIO_SORT_ORDER;
$this->enabled = ((MODULE_PAYMENT_PLISIO_STATUS == 'True') ? true : false);
}

function javascript_validation()
{
return false;
}

function selection()
{
return array('id' => $this->code, 'module' => $this->title);
}

function pre_confirmation_check()
{
return false;
}

function confirmation()
{
return false;
}

function process_button()
{
return false;
}

function before_process()
{
return false;
}

function after_process()
{
require_once(dirname(__FILE__) . "/Plisio/version.php");
require_once(dirname(__FILE__) . "/Plisio/Lib/PlisioClient.php");
global $insert_id, $order, $messageStack;

$info = $order->info;

$callback = zen_href_link('plisio_callback.php', $parameters='', $connection='NONSSL', $add_session_id=true, $search_engine_safe=true, $static=true );

$client = new PlisioClient\PlisioClient(MODULE_PAYMENT_PLISIO_API_KEY);
$params = array(
'order_name' => 'Order #' . $insert_id,
'order_number' => $insert_id,
'source_amount' => number_format($info['total'], 2, '.', ''),
'source_currency' => $info['currency'],
'callback_url' => $callback,
'cancel_url' => zen_href_link(FILENAME_CHECKOUT_PAYMENT),
'success_url' => zen_href_link(FILENAME_CHECKOUT_SUCCESS),
'email' => $order->customer['email_address'],
'plugin' => 'ZenCart',
'version' => PLISIO_ZENCART_EXTENSION_VERSION
);

$response = $client->createTransaction($params);
if ($response && $response['status'] !== 'error' && !empty($response['data'])) {
$_SESSION['cart']->reset(true);
zen_redirect($response['data']['invoice_url']);
} else {
$messageStack->add_session('checkout_payment', implode(',', json_decode($response['data']['message'], true)), 'error');
zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT));
return 'failed';
}
}

function get_error()
{
global $HTTP_GET_VARS;
return array('title' => MODULE_PAYMENT_PLISIO_ORDER_ERROR_TITLE,
'error' => $HTTP_GET_VARS['error']);
}

function check()
{
global $db;
if (!isset($this->_check)) {
$check_query = $db->Execute("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_PAYMENT_PLISIO_STATUS'");
$this->_check = $check_query->RecordCount();
}

return $this->_check;
}

function install()
{
global $db, $messageStack;
if (defined('MODULE_PAYMENT_PLISIO_STATUS')) {
$messageStack->add_session('Plisio module already installed.', 'error');
zen_redirect(zen_href_link(FILENAME_MODULES, 'set=payment&module=plisio', 'NONSSL'));
return 'failed';
}
$status_query = $db->Execute("select max(orders_status_id) as status_id from " . TABLE_ORDERS_STATUS);

$status_id = $status_query->fields['status_id']+1;
$status_id_paid = $status_id;
$status_id_pending = $status_id + 1;
$status_id_expired = $status_id + 2;
$status_id_cancelled = $status_id + 3;

$languages = zen_get_languages();

foreach ($languages as $lang) {
$db->Execute("insert into " . TABLE_ORDERS_STATUS . " (orders_status_id, language_id, orders_status_name) values ('" . $status_id_paid . "', '" . $lang['id'] . "', 'Plisio [Paid]')");
$db->Execute("insert into " . TABLE_ORDERS_STATUS . " (orders_status_id, language_id, orders_status_name) values ('" . $status_id_pending . "', '" . $lang['id'] . "', 'Plisio [Pending]')");
$db->Execute("insert into " . TABLE_ORDERS_STATUS . " (orders_status_id, language_id, orders_status_name) values ('" . $status_id_expired . "', '" . $lang['id'] . "', 'Plisio [Expired]')");
$db->Execute("insert into " . TABLE_ORDERS_STATUS . " (orders_status_id, language_id, orders_status_name) values ('" . $status_id_cancelled . "', '" . $lang['id'] . "', 'Plisio [Cancelled]')");
}

$flags_query = $db->Execute("describe " . TABLE_ORDERS_STATUS . " public_flag");
if ($flags_query->RecordCount() == 1) {
$db->Execute("update " . TABLE_ORDERS_STATUS . " set public_flag = 0 and downloads_flag = 0 where orders_status_id = '" . $status_id_paid . "'");
$db->Execute("update " . TABLE_ORDERS_STATUS . " set public_flag = 0 and downloads_flag = 0 where orders_status_id = '" . $status_id_pending . "'");
$db->Execute("update " . TABLE_ORDERS_STATUS . " set public_flag = 0 and downloads_flag = 0 where orders_status_id = '" . $status_id_expired . "'");
$db->Execute("update " . TABLE_ORDERS_STATUS . " set public_flag = 0 and downloads_flag = 0 where orders_status_id = '" . $status_id_cancelled . "'");
}

$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable Plisio Module', 'MODULE_PAYMENT_PLISIO_STATUS', 'False', 'Enable Plisio Payment Gateway plugin?', '6', '0', 'zen_cfg_select_option(array(\'True\', \'False\'), ', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Plisio API Key', 'MODULE_PAYMENT_PLISIO_API_KEY', '0', 'Your Plisio API Key', '6', '0', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort order of display.', 'MODULE_PAYMENT_PLISIO_SORT_ORDER', '0', 'Sort order of display. Lowest is displayed first.', '6', '8', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Plisio Order Status when order is pending', 'MODULE_PAYMENT_PLISIO_PENDING_STATUS_ID', '" . $status_id_pending . "', 'Status in your store when order is pending.<br />(\'Plisio [Pending]\' recommended)', '6', '5', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Plisio Order Status when order is cancelled', 'MODULE_PAYMENT_PLISIO_CANCELLED_STATUS_ID', '" . $status_id_cancelled . "', 'Status in your store when order is cancelled.<br />(\'Plisio [Cancelled]\' recommended)', '6', '5', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Plisio Order Status when order is expired', 'MODULE_PAYMENT_PLISIO_EXPIRED_STATUS_ID', '" . $status_id_expired . "', 'Status in your store when order is expired.<br />(\'Plisio [Expired]\' recommended)', '6', '5', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())");
$db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Plisio Order Status when order is paid', 'MODULE_PAYMENT_PLISIO_PAID_STATUS_ID', '" . $status_id_paid . "', 'Status in your store when order is paid.<br />(\'Plisio [Paid]\' recommended)', '6', '5', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())");
}

function remove ()
{
global $db;
$db->Execute("delete from " . TABLE_CONFIGURATION . " where configuration_key LIKE 'MODULE\_PAYMENT\_PLISIO\_%'");
$db->Execute("delete from " . TABLE_ORDERS_STATUS . " where LOWER(orders_status_name) LIKE '%plisio%'");
}

function keys()
{
return array(
'MODULE_PAYMENT_PLISIO_STATUS',
'MODULE_PAYMENT_PLISIO_API_KEY',
'MODULE_PAYMENT_PLISIO_SORT_ORDER',
'MODULE_PAYMENT_PLISIO_PENDING_STATUS_ID',
'MODULE_PAYMENT_PLISIO_PAID_STATUS_ID',
'MODULE_PAYMENT_PLISIO_CANCELLED_STATUS_ID',
'MODULE_PAYMENT_PLISIO_EXPIRED_STATUS_ID',
);
}
}
63 changes: 63 additions & 0 deletions plisio_callback.php
@@ -0,0 +1,63 @@
<?php

require('includes/application_top.php');

function verifyCallbackData($post, $apiKey)
{
if (!isset($post['verify_hash'])) {
return false;
}

$verifyHash = $post['verify_hash'];
unset($post['verify_hash']);
ksort($post);
if (isset($post['expire_utc'])){
$post['expire_utc'] = (string)$post['expire_utc'];
}
if (isset($post['tx_urls'])){
$post['tx_urls'] = html_entity_decode($post['tx_urls']);
}
$postString = serialize($post);
$checkKey = hash_hmac('sha1', $postString, $apiKey);
if ($checkKey != $verifyHash) {
return false;
}

return true;
}

global $db;

if (verifyCallbackData($_POST, MODULE_PAYMENT_PLISIO_API_KEY)) {
$order_id = $_REQUEST['order_number'];

$order = $db->Execute("select orders_id from " . TABLE_ORDERS . " where orders_id = '" . intval($order_id) . "' limit 1");
if ($order->RecordCount() <= 0) {
throw new Exception('Order #' . $order_id . ' does not exists');
}

switch ($_REQUEST['status']) {
case 'completed':
case 'mismatch':
$pl_order_status = MODULE_PAYMENT_PLISIO_PAID_STATUS_ID;
break;
case 'cancelled':
$pl_order_status = MODULE_PAYMENT_PLISIO_CANCELLED_STATUS_ID;
break;
case 'expired':
$pl_order_status = MODULE_PAYMENT_PLISIO_EXPIRED_STATUS_ID;
break;
case 'new':
$pl_order_status = MODULE_PAYMENT_PLISIO_PENDING_STATUS_ID;
break;
default:
$pl_order_status = NULL;
}

if ($pl_order_status) {
$db->Execute("update " . TABLE_ORDERS . " set orders_status = " . $pl_order_status . " where orders_id = " . intval($order_id));
}
echo 'OK';
} else {
echo 'Verify callback data failed';
}

0 comments on commit c925cb3

Please sign in to comment.