completed liman for using in sell and buy

This commit is contained in:
2026-05-24 22:29:43 +03:30
parent 81d4aa8926
commit 7f0f91701e
4 changed files with 591 additions and 99 deletions
@@ -23,6 +23,7 @@ use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
use Illuminate\Support\Facades\Http;
use App\Models\Setting;
use App\Models\Cnt;
use App\Services\LimanService;
class SingleOrderController extends Controller
@@ -31,11 +32,21 @@ class SingleOrderController extends Controller
{
$data = $request->all();
if($this->Config('goldir_price') == 'true'){
if ($this->Config('liman_price') == 'true') {
$liman_closed = Cnt::where('key', 'liman_closed')->value('value') == "true";
$liman_buy = Cnt::where('key', 'liman_open_buy')->value('value') == "false" && $data['direction'] == 1;
$liman_sell = Cnt::where('key', 'liman_open_sell')->value('value') == "false" && $data['direction'] == 2;
if ($liman_closed || $liman_buy || $liman_sell) {
throw new UnprocessableEntityHttpException('عدم ارائه سرویس.');
}
} elseif ($this->Config('goldir_price') == 'true') {
$goldir_closed = Cnt::where('key', 'goldir_closed')->first()['value'] == "true";
$goldir_buy = Cnt::where('key', 'goldir_open_buy')->first()['value'] == "false" && $data['direction'] == 1;
$goldir_sell = Cnt::where('key', 'goldir_open_sell')->first()['value'] == "false" && $data['direction'] == 2;
if($goldir_closed || $goldir_buy || $goldir_sell){
if ($goldir_closed || $goldir_buy || $goldir_sell) {
throw new UnprocessableEntityHttpException('عدم ارائه سرویس.');
}
}
@@ -180,7 +191,7 @@ class SingleOrderController extends Controller
], 1, true, false);
$response['1'] = 2;
//send to Goldir
$this->sendGoldir($data);
$this->sendProviderOrder($data, $wallet_interface, (int) $data['direction']);
return $response;
}
@@ -291,7 +302,7 @@ class SingleOrderController extends Controller
], 2, false, true);
//send to Goldir
$this->sendGoldir($data);
$this->sendProviderOrder($data, $wallet_interface, (int) $data['direction']);
}
@@ -459,6 +470,56 @@ class SingleOrderController extends Controller
$this->send($customer->mobile, $customerMessage);
}
private function sendProviderOrder(array &$data, $wallet_interface, int $direction)
{
if ($this->Config('liman_price') == "true") {
try {
return app(LimanService::class)->sendOrder($data);
} catch (UnprocessableEntityHttpException $e) {
$this->rollbackProviderFailedOrder($data, $wallet_interface, $direction);
throw $e;
} catch (\Throwable $e) {
$this->rollbackProviderFailedOrder($data, $wallet_interface, $direction);
throw new UnprocessableEntityHttpException(
'خطا در ثبت سفارش نزد لیمان: ' . $e->getMessage()
);
}
}
return $this->sendGoldir($data);
}
private function rollbackProviderFailedOrder(array $data, $wallet_interface, int $direction): void
{
$order = $data['order'] ?? null;
if (!$order instanceof Order) {
return;
}
if ($direction === 1) {
new TransactionInterface($wallet_interface, [
'cash' => $data['payment_amount'],
'gold' => $data['amount'],
'expire_at' => now(),
'active' => true,
'order_id' => $order->id,
'start_at' => now(),
], 2, false, true);
} else {
new TransactionInterface($wallet_interface, [
'gold' => $data['amount'],
'cash' => $data['total_price'],
'expire_at' => now(),
'active' => true,
'order_id' => $order->id,
], 1, true, false);
}
$order->delete();
}
private function sendGoldir($data)
{
if ($this->Config('send_to_goldir') == "true") {
+164 -93
View File
@@ -126,6 +126,7 @@ class ReportController extends Controller
$liman_open_sell = false;
$priceSource = null;
$priceValue = 0;
$toBool = function ($value) {
return filter_var($value, FILTER_VALIDATE_BOOLEAN);
@@ -133,7 +134,7 @@ class ReportController extends Controller
/*
|--------------------------------------------------------------------------
| بستن قیمت طبق منطق تابع اول
| بستن قیمت طبق منطق قبلی
|--------------------------------------------------------------------------
*/
if ($this->Config('close_price') == 'true') {
@@ -144,8 +145,8 @@ class ReportController extends Controller
[$endHour, $endMinute] = explode(':', $endDay);
$current = Carbon::now();
$start = Carbon::today()->setTime((int)$startHour, (int)$startMinute);
$end = Carbon::today()->setTime((int)$endHour, (int)$endMinute);
$start = Carbon::today()->setTime((int) $startHour, (int) $startMinute);
$end = Carbon::today()->setTime((int) $endHour, (int) $endMinute);
if (!$current->between($start, $end)) {
Cnt::where('key', 'app_closed')->update(['value' => "true"]);
@@ -164,16 +165,16 @@ class ReportController extends Controller
'closed' => true,
'time' => now()->format('H:i:s'),
];
} else {
Cnt::where('key', 'app_closed')->update(['value' => "false"]);
Cnt::where('key', 'goldir_closed')->update(['value' => "false"]);
Cnt::where('key', 'liman_closed')->update(['value' => "false"]);
}
Cnt::where('key', 'app_closed')->update(['value' => "false"]);
Cnt::where('key', 'goldir_closed')->update(['value' => "false"]);
Cnt::where('key', 'liman_closed')->update(['value' => "false"]);
}
/*
|--------------------------------------------------------------------------
| تنظیمات
| Settings
|--------------------------------------------------------------------------
*/
$settings = Setting::whereIn('key', [
@@ -192,97 +193,144 @@ class ReportController extends Controller
$gold_ir_price = $settingsMap->get('goldir_price');
$main_product_price = $settingsMap->get('main_product_price');
$diff_buy = (float) $settingsMap->get('buy_fee', 0);
$diff_sell = (float) $settingsMap->get('sell_fee', 0);
$diff_buy = (float) $settingsMap->get('buy_fee', $difference);
$diff_sell = (float) $settingsMap->get('sell_fee', $difference);
// این همون کلیدیه که تو عکس فرستادی
$liman_price_enabled = $toBool($this->Config('liman_price'));
\Log::info('LAST_PRICE DEBUG START', [
'file' => __FILE__,
'close_price' => $this->Config('close_price'),
'liman_price_raw' => $this->Config('liman_price'),
'liman_price_enabled' => $liman_price_enabled,
'liman_product_id' => $this->Config('liman_product_id'),
'liman_base_url' => $this->Config('liman_base_url'),
'liman_token_exists' => (bool) Setting::where('key', 'liman_token')->value('value'),
]);
/*
|--------------------------------------------------------------------------
| Liman - اولویت اول
| Montpar / Liman - اولویت اول
|--------------------------------------------------------------------------
*/
if ($liman_price_enabled && !$closed) {
try {
$liman = Http::timeout(7)
->withOptions([
'curl' => [
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
CURLOPT_TCP_FASTOPEN => 1,
]
])
->withToken(Setting::where('key', 'liman_token')->value('value'))
->get('http://212.23.201.173/server/customer/product/list')
->json();
$limanBaseUrl = rtrim($this->Config('liman_base_url') ?: 'https://montpar.ir', '/');
$limanProductId = (int) ($this->Config('liman_product_id') ?: 25);
if ((isset($liman['message']) && $liman['message'] == 'no authorised') || $liman == null) {
$newToken = app(LimanService::class)->liman_login();
$liman = app(LimanService::class)->productList();
$liman = Http::timeout(7)
->withToken($newToken)
->get('http://212.23.201.173/server/customer/product/list')
->json();
\Log::info('PROVIDER FIRST RESPONSE', [
'base_url' => $limanBaseUrl,
'product_id' => $limanProductId,
'type' => gettype($liman),
'message' => is_array($liman) ? ($liman['message'] ?? null) : null,
'available_ids' => is_array($liman) ? collect($liman)->pluck('id')->values()->all() : null,
]);
if (isset($liman['message'])) {
throw new \Exception('Provider message: ' . $liman['message']);
}
$collection = collect($liman);
$lpLiman = $collection->firstWhere('id', 25);
$lpLiman = $collection->firstWhere('id', $limanProductId);
if ($lpLiman && isset($lpLiman['sub_agent'])) {
$buy = (float) $lpLiman['sub_agent']['rate_buy_gram_price'];
$sell = (float) $lpLiman['sub_agent']['rate_sell_gram_price'];
\Log::info('PROVIDER PRODUCT PICKED', [
'base_url' => $limanBaseUrl,
'liman_product_id' => $limanProductId,
'found' => (bool) $lpLiman,
'has_sub_agent' => $lpLiman && isset($lpLiman['sub_agent']),
'open_buy' => $lpLiman['open_buy'] ?? null,
'open_sell' => $lpLiman['open_sell'] ?? null,
'buy_gram' => $lpLiman['sub_agent']['rate_buy_gram_price'] ?? null,
'sell_gram' => $lpLiman['sub_agent']['rate_sell_gram_price'] ?? null,
]);
$customPrice = [];
$customPrice['price'] = ($buy + $sell) / 2;
$customPrice['diff'] = ($buy - $sell) / 2;
if (!$lpLiman) {
throw new \Exception("Provider product not found. product_id={$limanProductId}");
}
Cnt::where('key', 'liman_price')->update(['value' => (float) $customPrice['price']]);
Cnt::where('key', 'liman_diff')->update(['value' => (float) $customPrice['diff']]);
if (!isset($lpLiman['sub_agent'])) {
throw new \Exception("Provider product has no sub_agent. product_id={$limanProductId}");
}
Cnt::where('key', 'liman_mazaneh')->update([
'value' => ((float) $customPrice['price'] * 4.331802)
]);
$buy = (float) ($lpLiman['sub_agent']['rate_buy_gram_price'] ?? 0);
$sell = (float) ($lpLiman['sub_agent']['rate_sell_gram_price'] ?? 0);
Cnt::where('key', 'liman_truly_buy_mazaneh')->update([
'value' => $lpLiman['sub_agent']['rate_buy_price']
]);
if ($buy <= 0 || $sell <= 0) {
throw new \Exception("Provider invalid gram price. buy={$buy}, sell={$sell}");
}
Cnt::where('key', 'liman_truly_sell_mazaneh')->update([
'value' => $lpLiman['sub_agent']['rate_sell_price']
]);
$customPrice = [];
$customPrice['price'] = ($buy + $sell) / 2;
$customPrice['diff'] = ($buy - $sell) / 2;
Cnt::where('key', 'log')->update([
'value' => json_encode($lpLiman, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)
]);
Cnt::where('key', 'liman_price')->update([
'value' => (float) $customPrice['price']
]);
$liman_open_sell = $toBool($lpLiman['open_sell'] ?? false);
$liman_open_buy = $toBool($lpLiman['open_buy'] ?? false);
Cnt::where('key', 'liman_diff')->update([
'value' => (float) $customPrice['diff']
]);
Cnt::where('key', 'liman_open_sell')->update([
'value' => $liman_open_sell ? "true" : "false"
]);
Cnt::where('key', 'liman_mazaneh')->update([
'value' => ((float) $customPrice['price'] * 4.331802)
]);
Cnt::where('key', 'liman_open_buy')->update([
'value' => $liman_open_buy ? "true" : "false"
]);
Cnt::where('key', 'liman_truly_buy_mazaneh')->update([
'value' => $lpLiman['sub_agent']['rate_buy_price'] ?? 0
]);
if ($liman_open_sell || $liman_open_buy) {
$liman_price = (int) $customPrice['price'];
}
Cnt::where('key', 'liman_truly_sell_mazaneh')->update([
'value' => $lpLiman['sub_agent']['rate_sell_price'] ?? 0
]);
Cnt::where('key', 'log')->update([
'value' => json_encode($lpLiman, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)
]);
$liman_open_sell = $toBool($lpLiman['open_sell'] ?? false);
$liman_open_buy = $toBool($lpLiman['open_buy'] ?? false);
Cnt::where('key', 'liman_open_sell')->update([
'value' => $liman_open_sell ? "true" : "false"
]);
Cnt::where('key', 'liman_open_buy')->update([
'value' => $liman_open_buy ? "true" : "false"
]);
if ($liman_open_sell || $liman_open_buy) {
$liman_price = (int) $customPrice['price'];
}
Cnt::where('key', 'liman_closed')->update([
'value' => $liman_price == 0 ? "true" : "false"
]);
} catch (\Exception $e) {
\Log::info('PROVIDER PRICE SUCCESS', [
'base_url' => $limanBaseUrl,
'liman_product_id' => $limanProductId,
'liman_price' => $liman_price,
'liman_diff' => $customPrice['diff'],
'open_buy' => $liman_open_buy,
'open_sell' => $liman_open_sell,
]);
} catch (\Throwable $e) {
$liman_price = 0;
\Log::error('PROVIDER PRICE ERROR', [
'base_url' => $limanBaseUrl ?? null,
'message' => $e->getMessage(),
'liman_product_id' => $limanProductId ?? null,
'liman_response' => $liman ?? null,
]);
Cnt::where('key', 'liman_closed')->update([
'value' => "true"
]);
}
}
/*
|--------------------------------------------------------------------------
| Goldir
@@ -322,8 +370,13 @@ class ReportController extends Controller
$customPrice['price'] = (ceil($buy) + ceil($sell)) / 2;
$customPrice['diff'] = (ceil($buy) - ceil($sell)) / 2;
Cnt::where('key', 'goldir_price')->update(['value' => (float) $customPrice['price']]);
Cnt::where('key', 'goldir_diff')->update(['value' => (float) $customPrice['diff']]);
Cnt::where('key', 'goldir_price')->update([
'value' => (float) $customPrice['price']
]);
Cnt::where('key', 'goldir_diff')->update([
'value' => (float) $customPrice['diff']
]);
Cnt::where('key', 'goldir_mazaneh')->update([
'value' => ((float) $customPrice['price'] * 4.331802)
@@ -360,7 +413,7 @@ class ReportController extends Controller
Cnt::where('key', 'goldir_closed')->update([
'value' => $goldir_price == 0 ? "true" : "false"
]);
} catch (\Exception $e) {
} catch (\Throwable $e) {
$goldir_price = 0;
Cnt::where('key', 'goldir_closed')->update([
@@ -402,7 +455,7 @@ class ReportController extends Controller
->json();
$tgn = (int) $taban_gohar['c'] * 10;
} catch (\Exception $e) {
} catch (\Throwable $e) {
$tgn = 0;
}
}
@@ -410,8 +463,8 @@ class ReportController extends Controller
/*
|--------------------------------------------------------------------------
| انتخاب قیمت اصلی
| اولویت جدید:
| Liman -> Goldir -> Taban Gohar -> Main Product
| اولویت:
| Liman/Montpar -> Goldir -> Taban Gohar -> Main Product
|--------------------------------------------------------------------------
*/
if ($liman_price_enabled && ($liman_price ?? 0) !== 0 && !$closed) {
@@ -428,6 +481,35 @@ class ReportController extends Controller
$priceSource = 'main_product';
} else {
$priceValue = 0;
$priceSource = null;
}
/*
|--------------------------------------------------------------------------
| اگر هیچ منبعی قیمت نداد، قیمت قبلی دیتابیس را برنگردان
|--------------------------------------------------------------------------
*/
if ($priceValue <= 0) {
\Log::warning('LAST_PRICE NO SOURCE PRICE', [
'liman_price' => $liman_price,
'goldir_price' => $goldir_price,
'taban_gohar' => $tgn,
'main_product' => $pr_price,
'price_source' => $priceSource,
]);
return [
'sell' => 0,
'buy' => 0,
'price_last' => 0,
'price' => 0,
'main_product' => $pr_price ?? 0,
'taban_gohar' => $tgn ?? 0,
'goldir' => $goldir_price ?? 0,
'liman' => $liman_price ?? 0,
'closed' => true,
'time' => now(),
];
}
/*
@@ -473,53 +555,41 @@ class ReportController extends Controller
}
}
$price = Price::orderBy('id', 'desc')->first();
if (!$price) {
return [];
}
$priceValue = $price->price;
/*
|--------------------------------------------------------------------------
| محاسبه sell / buy با حفظ ساختار خروجی تابع اول
| محاسبه sell / buy با همان priceValue همین اجرای فعلی
|--------------------------------------------------------------------------
*/
if ($priceSource === 'liman' && $liman_price !== 0) {
if ($priceSource === 'liman') {
$liman_profit = (float) Cnt::where('key', 'liman_diff')->value('value');
$final_buy_diff = $diff_buy + $liman_profit;
$final_sell_diff = $diff_sell + $liman_profit;
$sell = $priceValue !== 0
? ($liman_open_sell ? ceil($price->price - $final_sell_diff) : 0)
$sell = $liman_open_sell
? ceil($priceValue - $final_sell_diff)
: 0;
$buy = $priceValue !== 0
? ($liman_open_buy ? ceil($price->price + $final_buy_diff) : 0)
$buy = $liman_open_buy
? ceil($priceValue + $final_buy_diff)
: 0;
$priceLast = $priceValue !== 0
? ceil($price->price + $final_buy_diff)
: 0;
$priceLast = ceil($priceValue + $final_buy_diff);
} else {
if ($priceSource === 'goldir' && $goldir_price !== 0) {
$goldir_profit = (float) Cnt::where('key', 'goldir_diff')->value('value');
$difference = $goldir_profit;
}
$sell = $priceValue !== 0
? ($open_sell ? ceil($price->price - $difference) : 0)
$sell = $open_sell
? ceil($priceValue - $difference)
: 0;
$buy = $priceValue !== 0
? ($open_buy ? ceil($price->price + $difference) : 0)
$buy = $open_buy
? ceil($priceValue + $difference)
: 0;
$priceLast = $priceValue !== 0
? ceil($price->price + $difference)
: 0;
$priceLast = ceil($priceValue + $difference);
}
return [
@@ -531,11 +601,12 @@ class ReportController extends Controller
'taban_gohar' => $tgn ?? 0,
'goldir' => $goldir_price ?? 0,
'liman' => $liman_price ?? 0,
'closed' => $closed ?? null,
'closed' => false,
'time' => now(),
];
}
public function check()
{
$service = Http::
+4 -1
View File
@@ -13,6 +13,9 @@ class ConfigService
public function UpdateConfig($name, $value)
{
return Setting::where('key', $name)->update(['value' => $value]);
return Setting::updateOrCreate(
['key' => $name],
['value' => $value]
);
}
}
+358 -1
View File
@@ -2,10 +2,27 @@
namespace App\Services;
use App\Models\Cnt;
use App\Models\Order;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
class LimanService
{
private function baseUrl(): string
{
return rtrim(
app(ConfigService::class)->Config('liman_base_url') ?: 'https://montpar.ir',
'/'
);
}
private function endpoint(string $path): string
{
return $this->baseUrl() . '/' . ltrim($path, '/');
}
public function liman_login()
{
$config = app(ConfigService::class);
@@ -13,7 +30,7 @@ class LimanService
$mobile = $config->Config('liman_mobile');
$password = $config->Config('liman_password');
$liman = Http::timeout(10)->post('http://212.23.201.173/server/auth/login', [
$liman = Http::timeout(10)->post($this->endpoint('/server/auth/login'), [
'mobile' => $mobile,
'password' => $password,
'provider' => 'customer',
@@ -30,4 +47,344 @@ class LimanService
return $token;
}
public function getToken(): string
{
$token = trim((string) app(ConfigService::class)->Config('liman_token'));
if (!$token) {
$token = $this->liman_login();
}
return $token;
}
public function productList(): array
{
$token = $this->getToken();
$response = Http::timeout(7)
->withOptions([
'curl' => [
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
CURLOPT_TCP_FASTOPEN => 1,
]
])
->withToken($token)
->get($this->endpoint('/server/customer/product/list'))
->json();
if ((isset($response['message']) && $response['message'] === 'no authorised') || $response === null) {
$token = $this->liman_login();
$response = Http::timeout(7)
->withToken($token)
->get($this->endpoint('/server/customer/product/list'))
->json();
}
if (!is_array($response)) {
throw new \Exception('Provider product list response is not array');
}
return $response;
}
public function sendOrder(array &$data)
{
$payload = $this->makeOrderPayload($data);
$token = $this->getToken();
$httpResponse = $this->postToLiman(
$this->endpoint('/server/customer/order'),
$token,
$payload
);
$body = $this->decodeLimanHttpBody($httpResponse);
if (is_array($body) && ($body['message'] ?? null) === 'no authorised') {
$token = $this->liman_login();
$httpResponse = $this->postToLiman(
$this->endpoint('/server/customer/order'),
$token,
$payload
);
$body = $this->decodeLimanHttpBody($httpResponse);
}
$this->logLimanOrderResponse($httpResponse, $body);
$parsed = $this->parseLimanOrderResponse($body, (int) $data['direction']);
if (!$parsed['ok']) {
Log::warning('Liman order rejected', [
'base_url' => $this->baseUrl(),
'status' => $httpResponse->status(),
'body' => $body,
'raw' => $httpResponse->body(),
'payload' => $payload,
'reason' => $parsed['error'],
]);
throw new UnprocessableEntityHttpException(
$this->formatLimanErrorMessage($parsed['error'], $httpResponse)
);
}
$this->syncOrderWithLimanResponse($data, $parsed);
return $body;
}
private function makeOrderPayload(array $data): array
{
$mazaneh = ((int) $data['direction'] === 1)
? Cnt::where('key', 'liman_truly_buy_mazaneh')->value('value')
: Cnt::where('key', 'liman_truly_sell_mazaneh')->value('value');
$limanPrice = (float) Cnt::where('key', 'liman_price')->value('value');
$cash = (int) round(
$data['total_price'] ?? ($limanPrice * (float) $data['amount'])
);
$customerName = auth('customer')->check()
? auth('customer')->user()->name
: ($data['customer']['name'] ?? '');
return [
'mazaneh' => (int) $mazaneh,
'amount' => (float) $data['amount'],
'description' => app(ConfigService::class)->Config('name_fa') . ' - ' . $customerName,
'direction' => (int) $data['direction'],
'product_id' => (int) (app(ConfigService::class)->Config('liman_product_id') ?: 25),
'cash' => $cash,
'input_mode' => 'gold',
];
}
private function postToLiman(string $url, string $token, array $payload)
{
return Http::timeout(15)
->acceptJson()
->withToken($token)
->post($url, $payload);
}
private function decodeLimanHttpBody($httpResponse): ?array
{
$body = $httpResponse->json();
if (is_array($body)) {
return $body;
}
$raw = trim((string) $httpResponse->body());
if ($raw === '') {
return null;
}
$decoded = json_decode($raw, true);
if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
return $decoded;
}
return null;
}
private function logLimanOrderResponse($httpResponse, $body): void
{
try {
$value = $body === null
? $httpResponse->body()
: json_encode($body, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
Cnt::where('key', 'liman_order_response')->update(['value' => $value]);
Cnt::where('key', 'last_order_log')->update(['value' => $value]);
} catch (\Exception $e) {
Log::warning('Could not persist liman order response', [
'error' => $e->getMessage(),
]);
}
}
private function formatLimanErrorMessage(?string $error, $httpResponse): string
{
if ($error && $error !== 'پاسخ نامعتبر از سرور لیمان (اتصال یا فرمت JSON)') {
return $error;
}
$status = $httpResponse->status();
$raw = trim((string) $httpResponse->body());
if ($raw === '') {
return "خطا در ارتباط با لیمان (HTTP {$status})";
}
if (stripos($raw, '<!DOCTYPE') !== false || stripos($raw, '<html') !== false) {
return "خطا از سرویس لیمان (HTTP {$status}). پاسخ JSON دریافت نشد.";
}
return mb_substr($raw, 0, 300);
}
/**
* @return array{ok: bool, provider_id: ?int, error: ?string}
*/
private function parseLimanOrderResponse($body, int $direction): array
{
if (!is_array($body)) {
return [
'ok' => false,
'provider_id' => null,
'error' => 'پاسخ نامعتبر از سرور لیمان (اتصال یا فرمت JSON)',
];
}
if (!empty($body['message']) && is_string($body['message'])) {
if ($body['message'] === 'no authorised') {
return [
'ok' => false,
'provider_id' => null,
'error' => 'no authorised',
];
}
return [
'ok' => false,
'provider_id' => null,
'error' => $body['message'],
];
}
$providerId = $this->extractProviderOrderId($body);
if ($providerId !== null) {
return [
'ok' => true,
'provider_id' => $providerId,
'error' => null,
];
}
$sideKey = $direction === 1 ? 'buy' : 'sell';
if (($body[$sideKey] ?? null) === true) {
return [
'ok' => true,
'provider_id' => null,
'error' => null,
];
}
foreach ($body as $item) {
if (!is_array($item)) {
continue;
}
if (!empty($item['id']) && is_numeric($item['id'])) {
return [
'ok' => true,
'provider_id' => (int) $item['id'],
'error' => null,
];
}
if (!empty($item['order']['id'])) {
return [
'ok' => true,
'provider_id' => (int) $item['order']['id'],
'error' => null,
];
}
if (isset($item['sts']) && in_array((int) $item['sts'], [1, 2], true)) {
return [
'ok' => true,
'provider_id' => !empty($item['id']) ? (int) $item['id'] : null,
'error' => null,
];
}
}
return [
'ok' => false,
'provider_id' => null,
'error' => 'سفارشات توسط ارائه دهنده بسته شده است.',
];
}
private function extractProviderOrderId(array $body): ?int
{
if (!empty($body['id'])) {
return (int) $body['id'];
}
if (!empty($body['order']['id'])) {
return (int) $body['order']['id'];
}
if (isset($body[1]) && is_array($body[1])) {
if (!empty($body[1]['id'])) {
return (int) $body[1]['id'];
}
if (!empty($body[1]['order']['id'])) {
return (int) $body[1]['order']['id'];
}
}
if (isset($body[2]) && is_array($body[2]) && !empty($body[2]['id'])) {
return (int) $body[2]['id'];
}
foreach (['buy', 'sell'] as $sideKey) {
if (!isset($body[$sideKey]) || !is_array($body[$sideKey])) {
continue;
}
if (!empty($body[$sideKey]['id'])) {
return (int) $body[$sideKey]['id'];
}
if (!empty($body[$sideKey]['order']['id'])) {
return (int) $body[$sideKey]['order']['id'];
}
}
return null;
}
private function syncOrderWithLimanResponse(array &$data, array $parsed): void
{
$limanDiff = (float) Cnt::where('key', 'liman_diff')->value('value');
$limanPrice = (float) Cnt::where('key', 'liman_price')->value('value');
$totalPriceLiman = ((int) $data['direction'] === 1)
? ($limanPrice + $limanDiff)
: ($limanPrice - $limanDiff);
$providerOrderId = $parsed['provider_id'] ?? null;
if (isset($data['order']) && $data['order'] instanceof Order) {
if ($providerOrderId !== null) {
$data['order']->provider_id = $providerOrderId;
}
$data['order']->total_price_liman = $totalPriceLiman;
$data['order']->save();
}
$data['total_price_liman'] = $totalPriceLiman;
if ($providerOrderId !== null) {
$data['provider_id'] = $providerOrderId;
}
}
}