За последние 24 часа нас посетил 22691 программист и 1281 робот. Сейчас ищут 787 программистов ...

Нужна помощь с Конвертером валют (Он же обменник)

Тема в разделе "Прочие вопросы по PHP", создана пользователем Darek, 1 фев 2021.

  1. Darek

    Darek Активный пользователь

    С нами с:
    23 апр 2018
    Сообщения:
    7
    Симпатии:
    0
    Всем привет. Ситуация такая:
    Имеется у меня очень полезный и интересный для меня скрипт (готовый сайт), в нём присутствует обмен валют с парсом курсов через API. Ломаю голову и сёрфил несколько дней (ну не доходит до дурака).
    Суть проблем:
    Имеется 3 валюты - RUB, USD, EUR
    1. 1. Проблема Обмена
    • Обмен RUB в USD - 1к1, хотя отображает курс и должно по нему менять. (В обратную сторону работает правильно)
    • Обмен RUB в EUR - Идентично выше описанному.
    • Обмен EUR в USD - идентично выше описанному.
    1. 2. Обмен валюты на саму себя
    • Меняя любую валюту на саму себя, к примеру 50 RUB в 50 RUB - комиссия системы (в моём случае 2%) не списывается у пользователя, а наоборот прибавляется к сумме обмена.
    PHP:
    1. function PW_currencyConvertor($amount,$from_Currency,$to_Currency) {
    2.     global $db, $settings;
    3.     $am = urlencode($amount);
    4.     $prefix = $from_Currency.'_'.$to_Currency;
    5.     $ch = curl_init();
    6.    
    7.    
    8.     $url = "https://free.currconv.com/api/v7/convert?q=$prefix&compact=ultra&apiKey=$settings[curcnv_api]";
    9.    
    10.     // Disable SSL verification
    11.     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    12.     // Will return the response, if false it print the response
    13.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    14.     // Set the url
    15.     curl_setopt($ch, CURLOPT_URL,$url);
    16.     // Execute
    17.     $result=curl_exec($ch);
    18.     // Closing
    19.     curl_close($ch);
    20.     $json = json_decode($result, true);
    21.     //echo $json[$prefix]['val'];
    22.     $converted_amount = $json[$prefix];
    23.     if($amount>1 && $from_Currency  != "USD") {
    24.         $converted_amount = $amount * $converted_amount;
    25.         return number_format($converted_amount, 2, '.', '');
    26.     } elseif($amount>1 && $to_Currency  != "USD") {
    27.         $converted_amount = $amount * $converted_amount;
    28.         return number_format($converted_amount, 2, '.', '');
    29.     } else {
    30.         return number_format($converted_amount, 2, '.', '');
    31.     }
    32. }
    33.  
    34. function PW_GetRates($from_currency,$to_currency) {
    35.     global $db, $settings;
    36.     $data = array();
    37.     if(empty($from_currency) or empty($to_currency)) {
    38.         $data['status'] = 'error';
    39.         $data['msg'] = 'Some of currencies are missing.';
    40.     } else {
    41.         $fee = $settings['curcnv_fee_percentage'];
    42.         $rate_from = 1;
    43.         $calculate = PW_currencyConvertor($rate_from,$from_currency,$to_currency);
    44.         $calculate1 = ($calculate * $fee) / 100;
    45.         $calculate2 = $calculate - $calculate1;
    46.         if($calculate2 < 1) {
    47.             $calculate = PW_currencyConvertor($rate_from,$to_currency,$from_currency);
    48.             $calculate1 = ($calculate * $fee) / 100;
    49.             $calculate2 = $calculate - $calculate1;
    50.             $rate_from = number_format($calculate2, 2, '.', '');
    51.             $rate_to = 1;
    52.         } else {
    53.             $rate_to = number_format($calculate2, 2, '.', '');
    54.         }
    55.         $data['status'] = 'success';
    56.         $data['rate_from'] = $rate_from;
    57.         $data['rate_to'] = $rate_to;
    58.         $data['currency_from'] = $from_currency;
    59.         $data['currency_to'] = $to_currency;
    60.         $data['fee'] = $calculate1;
    61.     }
    62.     return $data;
    63. }
    Подскажите, может что то не доглядел, буду очень признателен.
    Убедительная просьба не писать по типу "Го ПМ или Го ЛС, Сделаю Платно".
    Я делаю всё сам, не хватает навыков, по этому обратился и прошу указать на ошибку.
    Спасибо за понимание!
     
  2. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    Тут важно понять, что продажа и покупка ведется за одну и ту же валюту.
    Покупаете за рубли и продаете за рубли.
    Курсы покупки и продажи разные. Продаете дороже, чем покупаете. Не наоборот.
    Если же вам принесли доллары, а хотят евро, то вы сначала покупаете доллары за рубли по курсу покупки, а потом за них же продаете евро по курсу продажи евро.
    Если же продавать напрямую, то тут нужен так называемый кросс курс. Его нужно или высчитывать или скачивать отдельно.
    Что-то еще?
     
  3. Darek

    Darek Активный пользователь

    С нами с:
    23 апр 2018
    Сообщения:
    7
    Симпатии:
    0
    Ну это то я понял, иначе бы не сделал то что уже имеется. А вот причину проблем не догоняю. Вроде всё правильно, по сути берет курс с Апи для валютной пары. Но почему для одних он берет правильный, а для других по той же схеме берет верный но конвертирует по курсу 1 к 1
     
  4. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    Возможно потому, что курсы представлены в разных валютах.
    Это не банковский курс. Биржевые котировки например.
    Или это те же кросс курсы.
    Приведите пример того, что скачиваете.
     
  5. Darek

    Darek Активный пользователь

    С нами с:
    23 апр 2018
    Сообщения:
    7
    Симпатии:
    0
    Какой именно пример?
    По функции видно что запрашивает курс одной пары (небольшой обход сделал) $prefix - валютные пары которые беруться с базы. Если обмен происходит в одну сторону, то в другую с курсом 1к1.
    В то же время переходя по линке апи, я вижу курс, и вполне соответствующий ЦБРФ.
     
  6. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    json из которого извлекаете курс валюты.
     
  7. Darek

    Darek Активный пользователь

    С нами с:
    23 апр 2018
    Сообщения:
    7
    Симпатии:
    0
    Интересно каким же образом.?
     
  8. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    Например прямую ссылку него.
     
  9. Darek

    Darek Активный пользователь

    С нами с:
    23 апр 2018
    Сообщения:
    7
    Симпатии:
    0
    Курсы извлекаются напрямую из стороннего ресурса. ссылка под спойлером имеется на сам апи.
    На стороне моего сервера никаких данных кроме From_To&Amount не передается.
     
  10. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.476
    Симпатии:
    281
    ОК.
    Чем мог помог.
    Следующий.
     
  11. Darek

    Darek Активный пользователь

    С нами с:
    23 апр 2018
    Сообщения:
    7
    Симпатии:
    0
    Спасибо. хотя подумываю уже заменить просто курсы напрямую используя АПИ ЦБРФ.
    Как то так
    PHP:
    1. class CurrencyConverter {
    2.    
    3.     /*
    4.      * Класс для конвертации валют
    5.      */
    6.  
    7. // PROPERTIES
    8.  
    9.     protected $fromCurrencyAmount;
    10.     protected $fromCurrencyName = 'RUB';
    11.     protected $fromCurrencyRate;
    12.     protected $toCurrencyAmount;
    13.     protected $toCurrencyName = 'RUB';
    14.     protected $toCurrencyRate;
    15.     protected $precision = 1;
    16.  
    17. // API
    18.  
    19.     public function from($currencyName) {
    20.         $this->fromCurrencyName = $currencyName;
    21.         return $this;
    22.     }
    23.  
    24.     public function to($currencyName) {
    25.         $this->toCurrencyName = $currencyName;
    26.         return $this;
    27.     }
    28.  
    29.     public function precision($precision) {
    30.         $this->precision = $precision;
    31.         return $this;
    32.     }
    33.  
    34.     public function convert($fromCurrencyAmount) {
    35.         if ($this->fromCurrencyName != 'RUB') {
    36.             $this->fromCurrencyRate = $this->GetRate($this->fromCurrencyName);
    37.         } else {
    38.             $this->fromCurrencyRate = 1;
    39.         }
    40.  
    41.         if ($this->toCurrencyName != 'RUB') {
    42.             $this->toCurrencyRate = $this->GetRate($this->toCurrencyName);
    43.         } else {
    44.             $this->toCurrencyRate = 1;
    45.         }
    46.  
    47.         $result = $fromCurrencyAmount / $this->fromCurrencyRate * $this->toCurrencyRate;
    48.         $this->toCurrencyAmount = round($result, $this->precision);
    49.         return $this->toCurrencyAmount;
    50.     }
    51.  
    52. // PROTECTED
    53.  
    54.     private function today() {
    55.         return date('d/m/Y');
    56.     }
    57.  
    58.     private function GetXML() {
    59.         $r = file_get_contents('http://www.cbr.ru/scripts/XML_daily.asp?date_req='.$this->today());
    60.         $xml = simplexml_load_string($r);
    61.         return $xml;
    62.     }
    63.  
    64.     private function GetRateFromXML($currency) {
    65.             $xml = $this->GetXML();
    66.             foreach ($xml->Valute as $valute) {
    67.                     if ($valute->CharCode == $currency) {
    68.                             $value = str_replace(',', '.', $valute->Value);
    69.                             $rate = $valute->Nominal / $value;
    70.                     }
    71.             }
    72.             if (isset($rate)) {
    73.                     $r = $rate;
    74.             } else {
    75.                     $r = false;
    76.             }
    77.             return $r;
    78.     }
    79.  
    80.     private function GetRateFromCookie($currency) {
    81.             if ($this->IsSetCurrencyCookie($currency)) {
    82.                     $parts = explode('_', $this->GetRateCookie($currency));
    83.                     $rate = $parts[0];
    84.                     $r = $rate;
    85.             } else {
    86.                     $r = false;
    87.             }
    88.             return $r;
    89.     }
    90.  
    91.     private function SetRateCookie($currency, $rate) {
    92.             setcookie($currency, $rate.'_'.$this->today());
    93.     }
    94.  
    95.     private function GetRateCookie($currency) {
    96.             return filter_input(INPUT_COOKIE, $currency);
    97.     }
    98.  
    99.     private function IsSetCurrencyCookie($currency){
    100.         if ($this->GetRateCookie($currency) != FALSE and $this->GetRateCookie($currency) != NULL) {
    101.             return TRUE;
    102.         }else {
    103.             return FALSE;
    104.         }
    105.     }
    106.  
    107.     private function GetRate($currency) {
    108.             if ($this->IsSetCurrencyCookie($currency)) {
    109.                     $parts = explode('_', $this->GetRateCookie($currency));
    110.                     $date = $parts[1];
    111.                     if ($date == $this->today()) {
    112.                             $rate = $this->GetRateFromCookie($currency);
    113.                     } else {
    114.                             $rate = $this->GetRateFromXML($currency);
    115.                             $this->SetRateCookie($currency, $rate);
    116.                     }
    117.             } else {
    118.                     $rate = $this->GetRateFromXML($currency);
    119.                     $this->SetRateCookie($currency, $rate);
    120.             }
    121.             return $rate;
    122.     }