Skip to content

Commit

Permalink
release
Browse files Browse the repository at this point in the history
  • Loading branch information
wh1teend committed Apr 25, 2023
1 parent 310217e commit ac32fcc
Show file tree
Hide file tree
Showing 31 changed files with 333 additions and 0 deletions.
208 changes: 208 additions & 0 deletions Payment/LiqPay.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
<?php

namespace WH1\PaygateLiqPay\Payment;

use Exception;
use XF;
use XF\Entity\PaymentProfile;
use XF\Entity\PurchaseRequest;
use XF\Http\Request;
use XF\Mvc\Controller;
use XF\Payment\AbstractProvider;
use XF\Payment\CallbackState;
use XF\Purchasable\Purchase;

class LiqPay extends AbstractProvider
{
public function getTitle(): string
{
return 'LiqPay';
}

public function getApiEndpoint(): string
{
return 'https://www.liqpay.ua/api/3/checkout';
}

public function verifyConfig(array &$options, &$errors = []): bool
{
if (empty($options['private_key']) || empty($options['public_key']))
{
$errors[] = XF::phrase('wh1_liqpay_you_must_provide_all_data');
}

return !$errors;
}

public function getPaymentParams(PurchaseRequest $purchaseRequest, Purchase $purchase): array
{
$profileOptions = $purchase->paymentProfile->options;

$payment = [
'version' => 3,
'public_key' => $profileOptions['public_key'],
'action' => 'pay',
'amount' => $purchase->cost,
'currency' => $purchase->currency,
'description' => $purchase->title,
'order_id' => $purchaseRequest->request_key,

'result_url' => $purchase->returnUrl,
'server_url' => $this->getCallbackUrl(),
];

return $this->getDataAndSignature($payment, $profileOptions['private_key']);
}

public function initiatePayment(Controller $controller, PurchaseRequest $purchaseRequest, Purchase $purchase): XF\Mvc\Reply\Redirect
{
$paymentParams = $this->getPaymentParams($purchaseRequest, $purchase);

return $controller->redirect($this->getApiEndpoint() . '?' . http_build_query($paymentParams));
}

public function setupCallback(Request $request): CallbackState
{
$state = new CallbackState();

$state->dataRaw = $request->filter('data', 'str');
$state->data = json_decode(base64_decode($state->dataRaw), true);
$state->signature = $request->filter('signature', 'str');

$state->amount = $state->data['amount'] ?? 0;
$state->currency = $state->data['currency'] ?? '';
$state->status = $state->data['status'] ?? '';
$state->subscriberId = $state->data['customer'] ?? 0;

$state->ip = $request->getIp();

$state->httpCode = 200;

return $state;
}

public function validateCallback(CallbackState $state): bool
{
$state->requestKey = $state->data['order_id'] ?? '';
$state->transactionId = $state->input['payment_id'] ?? '';

if (!empty($state->signature) && $state->data['version'] == 3 && $state->data['action'] == 'pay')
{
return true;
}

$state->logType = 'info';
$state->logMessage = 'Auth failed';

return false;
}

public function validateTransaction(CallbackState $state): bool
{
if (!$state->requestKey)
{
$state->logType = 'info';
$state->logMessage = 'Metadata is empty!';

return false;
}

if(!empty($state->data['err_code']))
{
$state->logType = 'error';
$state->logMessage = $state->data['err_description'] ?? $state->data['err_code'];

return false;
}

return parent::validateTransaction($state);
}

public function validatePurchasableData(CallbackState $state): bool
{
$paymentProfile = $state->getPaymentProfile();

$options = $paymentProfile->options;
if (!empty($options['public_key']) && !empty($options['private_key']) && !empty($state->signature))
{
if ($this->verifySignature($state->dataRaw, $state->signature, $options['private_key']))
{
return true;
}

$state->logType = 'error';
$state->logMessage = "Invalid signature";

return false;
}

$state->logType = 'error';
$state->logMessage = 'Invalid public_key or secret_key.';

return false;
}

public function validateCost(CallbackState $state): bool
{
$purchaseRequest = $state->getPurchaseRequest();

if (($state->currency == $purchaseRequest->cost_currency)
&& round($state->amount, 2) == round($purchaseRequest->cost_amount, 2))
{
return true;
}

$state->logType = 'error';
$state->logMessage = 'Invalid cost amount.';

return false;
}

public function getPaymentResult(CallbackState $state): void
{
if (strtolower($state->status) == 'success')
{
$state->paymentResult = CallbackState::PAYMENT_RECEIVED;
}
}

public function prepareLogData(CallbackState $state): void
{
$state->logDetails = array_merge($state->data, [
'ip' => $state->ip,
'signature' => $state->signature
]);
}

public function verifyCurrency(PaymentProfile $paymentProfile, $currencyCode): bool
{
return in_array($currencyCode, $this->supportedCurrencies);
}

protected $supportedCurrencies = [
'RUB', 'USD', 'EUR', 'UAH', 'BYN', 'KZT'
];

public function supportsRecurring(PaymentProfile $paymentProfile, $unit, $amount, &$result = self::ERR_NO_RECURRING): bool
{
$result = self::ERR_NO_RECURRING;

return false;
}

protected function getDataAndSignature(array $payment, string $privateKey): array
{
$data = base64_encode(json_encode($payment));
$signature = base64_encode(hash('sha1', $privateKey . $data . $privateKey, true));

return [
'data' => $data,
'signature' => $signature
];
}

protected function verifySignature(string $data, string $signature, string $privateKey): bool
{
return hash_equals($signature, base64_encode(hash('sha1', $privateKey . $data . $privateKey, true)));
}
}
34 changes: 34 additions & 0 deletions Setup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace WH1\PaygateLiqPay;

use XF\AddOn\AbstractSetup;
use XF\AddOn\StepRunnerInstallTrait;
use XF\AddOn\StepRunnerUninstallTrait;
use XF\AddOn\StepRunnerUpgradeTrait;

class Setup extends AbstractSetup
{
use StepRunnerInstallTrait;
use StepRunnerUpgradeTrait;
use StepRunnerUninstallTrait;

public function installStep1()
{
$db = $this->db();

$db->insert('xf_payment_provider', [
'provider_id' => "wh1LiqPay",
'provider_class' => "WH1\\PaygateLiqPay:LiqPay",
'addon_id' => "WH1/PaygateLiqPay"
]);
}

public function uninstallStep1()
{
$db = $this->db();

$db->delete('xf_payment_profile', "provider_id = 'wh1LiqPay'");
$db->delete('xf_payment_provider', "provider_id = 'wh1LiqPay'");
}
}
2 changes: 2 additions & 0 deletions _data/activity_summary_definitions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<activity_summary_definitions/>
2 changes: 2 additions & 0 deletions _data/admin_navigation.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<admin_navigation/>
2 changes: 2 additions & 0 deletions _data/admin_permission.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<admin_permission/>
2 changes: 2 additions & 0 deletions _data/advertising_positions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<advertising_positions/>
2 changes: 2 additions & 0 deletions _data/api_scopes.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<api_scopes/>
2 changes: 2 additions & 0 deletions _data/bb_code_media_sites.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<bb_code_media_sites/>
2 changes: 2 additions & 0 deletions _data/bb_codes.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<bb_codes/>
2 changes: 2 additions & 0 deletions _data/class_extensions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<class_extensions/>
2 changes: 2 additions & 0 deletions _data/code_event_listeners.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<code_event_listeners/>
2 changes: 2 additions & 0 deletions _data/code_events.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<code_events/>
2 changes: 2 additions & 0 deletions _data/content_type_fields.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<content_type_fields/>
2 changes: 2 additions & 0 deletions _data/cron.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<cron/>
2 changes: 2 additions & 0 deletions _data/help_pages.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<help_pages/>
2 changes: 2 additions & 0 deletions _data/member_stats.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<member_stats/>
2 changes: 2 additions & 0 deletions _data/navigation.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation/>
2 changes: 2 additions & 0 deletions _data/option_groups.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<option_groups/>
2 changes: 2 additions & 0 deletions _data/options.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<options/>
2 changes: 2 additions & 0 deletions _data/permission_interface_groups.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<permission_interface_groups/>
2 changes: 2 additions & 0 deletions _data/permissions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<permissions/>
6 changes: 6 additions & 0 deletions _data/phrases.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<phrases>
<phrase title="wh1_liqpay_private_key" version_id="1" version_string="1"><![CDATA[Private key]]></phrase>
<phrase title="wh1_liqpay_public_key" version_id="1" version_string="1"><![CDATA[Public key]]></phrase>
<phrase title="wh1_liqpay_you_must_provide_all_data" version_id="1" version_string="1"><![CDATA[You must provide all data]]></phrase>
</phrases>
2 changes: 2 additions & 0 deletions _data/routes.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<routes/>
2 changes: 2 additions & 0 deletions _data/style_properties.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<style_properties/>
2 changes: 2 additions & 0 deletions _data/style_property_groups.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<style_property_groups/>
2 changes: 2 additions & 0 deletions _data/template_modifications.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<template_modifications/>
12 changes: 12 additions & 0 deletions _data/templates.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<templates>
<template type="admin" title="payment_profile_wh1LiqPay" version_id="1" version_string="1"><![CDATA[<xf:textboxrow name="options[public_key]" value="{$profile.options.public_key}"
label="{{ phrase('wh1_liqpay_public_key') }}"
hint="{{ phrase('required') }}">
</xf:textboxrow>
<xf:textboxrow name="options[private_key]" value="{$profile.options.private_key}"
label="{{ phrase('wh1_liqpay_private_key') }}"
hint="{{ phrase('required') }}">
</xf:textboxrow>]]></template>
</templates>
2 changes: 2 additions & 0 deletions _data/widget_definitions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<widget_definitions/>
2 changes: 2 additions & 0 deletions _data/widget_positions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<widget_positions/>
23 changes: 23 additions & 0 deletions addon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"legacy_addon_id": "",
"title": "[WH1] Paygate: LiqPay",
"description": "LiqPay payment profile for XenForo.",
"version_id": 1000070,
"version_string": "1.0.0",
"dev": "wh1teend",
"dev_url": "https://t.me/wh1teend",
"faq_url": "",
"support_url": "",
"extra_urls": [],
"require": {
"php": [
"7.4",
"PHP 7.4+"
],
"XF": [
2010270,
"XenForo 2.1.2+"
]
},
"icon": "icon.png"
}
Binary file added icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit ac32fcc

Please sign in to comment.