Passed
Push — main ( 4aef09...4747c4 )
by Miaad
01:45
created

crypto::createPayment()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 13
c 1
b 0
f 0
nc 1
nop 12
dl 0
loc 14
rs 9.8333

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace BPT\pay;
4
5
use BPT\pay\crypto\invoicePaymentInterface;
6
use BPT\pay\crypto\estimatePriceInterface;
7
use BPT\pay\crypto\estimateUpdateInterface;
8
use BPT\pay\crypto\invoiceResponseInterface;
9
use BPT\pay\crypto\ipnDataInterface;
10
use BPT\pay\crypto\paymentInterface;
11
use BPT\settings;
12
use BPT\tools;
13
use CurlHandle;
14
15
class crypto {
16
    private static string $api_key = '';
17
18
    private static string $ipn_secret = '';
19
20
    const API_BASE = 'https://api.nowpayments.io/v1/';
21
22
    private static CurlHandle $session;
23
24
    public static function init (): void {
25
        self::$api_key = settings::$pay['crypto']['api_key'] ?? '';
26
        self::$ipn_secret = settings::$pay['crypto']['ipn_secret'] ?? '';
27
        self::$session = curl_init();
28
        curl_setopt(self::$session, CURLOPT_RETURNTRANSFER, true);
29
        curl_setopt(self::$session, CURLOPT_SSL_VERIFYPEER, 1);
30
        curl_setopt(self::$session, CURLOPT_SSL_VERIFYHOST, 2);
31
    }
32
33
    private static function execute (string $method, string $endpoint, string|array $data = '') {
34
        if (is_array($data)) {
35
            foreach ($data as $key => $value) {
36
                if (empty($value)) {
37
                    unset($data[$key]);
38
                }
39
            }
40
        }
41
42
        $session = self::$session;
43
        curl_setopt($session, CURLOPT_HTTPHEADER, [
44
            'X-API-KEY: ' . self::$api_key,
45
            'Content-Type: application/json'
46
        ]);
47
        switch ($method) {
48
            case 'GET':
49
                curl_setopt($session, CURLOPT_URL, self::API_BASE . $endpoint . !empty($data) && is_array($data) ? ('?' . http_build_query($data)) : '');
50
                break;
51
            case 'POST':
52
                curl_setopt($session, CURLOPT_POST, true);
53
                curl_setopt($session, CURLOPT_POSTFIELDS, json_encode($data));
54
                curl_setopt($session, CURLOPT_URL, self::API_BASE . $endpoint);
55
                break;
56
            default:
57
                return false;
58
        }
59
        return json_decode(curl_exec($session));
0 ignored issues
show
Bug introduced by
It seems like curl_exec($session) can also be of type true; however, parameter $json of json_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

59
        return json_decode(/** @scrutinizer ignore-type */ curl_exec($session));
Loading history...
60
    }
61
62
    public static function status (): bool {
63
        return self::execute('GET', 'status')->message === 'OK';
64
    }
65
66
    /**
67
     * @return estimatePriceInterface|mixed
68
     */
69
    public static function getEstimatePrice (int|float $amount, string $currency_from, string $currency_to) {
70
        return self::execute('GET', 'estimate', [
71
            'amount'        => $amount,
72
            'currency_from' => $currency_from,
73
            'currency_to'   => $currency_to
74
        ]);
75
    }
76
77
    /**
78
     * @return invoicePaymentInterface|mixed
79
     */
80
    public static function createPayment (int|float $price_amount, string $price_currency, string $pay_currency, int|float $pay_amount = null, string $ipn_callback_url = null, string $order_id = null, string $order_description = null, string $purchase_id = null, string $payout_address = null, string $payout_currency = null, string $payout_extra_id = null, bool $fixed_rate = null) {
81
        return self::execute('POST', 'payment', [
82
            'price_amount'      => $price_amount,
83
            'price_currency'    => $price_currency,
84
            'pay_currency'      => $pay_currency,
85
            'pay_amount'        => $pay_amount,
86
            'ipn_callback_url'  => $ipn_callback_url,
87
            'order_id'          => $order_id,
88
            'order_description' => $order_description,
89
            'purchase_id'       => $purchase_id,
90
            'payout_address'    => $payout_address,
91
            'payout_currency'   => $payout_currency,
92
            'payout_extra_id'   => $payout_extra_id,
93
            'fixed_rate'        => $fixed_rate
94
        ]);
95
    }
96
97
    /**
98
     * @return invoicePaymentInterface|mixed
99
     */
100
    public static function createInvoicePayment (string $iid, string $pay_currency, string $purchase_id = null, string $order_description = null, string $customer_email = null, string $payout_address = null, string $payout_extra_id = null, string $payout_currency = null) {
101
        return self::execute('POST', 'invoice', [
102
            'iid'               => $iid,
103
            'pay_currency'      => $pay_currency,
104
            'purchase_id'       => $purchase_id,
105
            'order_description' => $order_description,
106
            'customer_email'    => $customer_email,
107
            'payout_address'    => $payout_address,
108
            'payout_extra_id'   => $payout_extra_id,
109
            'payout_currency'   => $payout_currency
110
        ]);
111
    }
112
113
    /**
114
     * @return estimateUpdateInterface|mixed
115
     */
116
    public static function updateEstimatePrice (int $paymentID) {
117
        return self::execute('POST', 'payment/' . $paymentID . '/update-merchant-estimate');
118
    }
119
120
    /**
121
     * @return paymentInterface|mixed
122
     */
123
    public static function getPaymentStatus (int $paymentID) {
124
        return self::execute('GET', 'payment/' . $paymentID);
125
    }
126
127
    public static function getMinimumPaymentAmount (string $currency_from, string $currency_to): float {
128
        return self::execute('GET', 'min-amount', [
129
            'currency_from' => $currency_from,
130
            'currency_to'   => $currency_to
131
        ])->min_amount;
132
    }
133
134
    /**
135
     * @return invoiceResponseInterface|mixed
136
     */
137
    public static function createInvoice (int|float $price_amount, string $price_currency, string $pay_currency, int|float $pay_amount = null, string $ipn_callback_url = null, string $order_id = null, string $order_description = null, string $success_url = null, string $cancel_url = null) {
138
        return self::execute('POST', 'invoice', [
139
            'price_amount'      => $price_amount,
140
            'price_currency'    => $price_currency,
141
            'pay_currency'      => $pay_currency,
142
            'pay_amount'        => $pay_amount,
143
            'ipn_callback_url'  => $ipn_callback_url,
144
            'order_id'          => $order_id,
145
            'order_description' => $order_description,
146
            'success_url'       => $success_url,
147
            'cancel_url'        => $cancel_url
148
        ]);
149
    }
150
151
    public static function getCurrencies (): array {
152
        return self::execute('GET', 'currencies')->currencies;
153
    }
154
155
    public static function isNowPayments(): bool {
156
        $ip = $_SERVER['REMOTE_ADDR'];
157
        if (settings::$cloudflare_verify) {
158
            if (isset($_SERVER['HTTP_CF_CONNECTING_IP']) && tools::isCloudFlare($ip)) {
159
                $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
160
            }
161
        }
162
        elseif (settings::$arvancloud_verify && isset($_SERVER['HTTP_AR_REAL_IP']) && tools::isArvanCloud($ip)) {
163
            $ip = $_SERVER['HTTP_AR_REAL_IP'];
164
        }
165
166
        return $ip === '144.76.201.30';
167
    }
168
169
    public static function isIPNRequestValid (): bool {
170
        if (empty($_SERVER['HTTP_X_NOWPAYMENTS_SIG'])) {
171
            return false;
172
        }
173
        if (!self::isNowPayments()) {
174
            return false;
175
        }
176
        $request_json = file_get_contents('php://input');
177
        if (empty($request_json)) {
178
            return false;
179
        }
180
        $request_data = json_decode($request_json, true);
181
        ksort($request_data);
182
        $hmac = hash_hmac("sha512", json_encode($request_data, JSON_UNESCAPED_SLASHES), trim(self::$ipn_secret));
183
        return $hmac == $_SERVER['HTTP_X_NOWPAYMENTS_SIG'];
184
    }
185
186
    /**
187
     * @return ipnDataInterface|mixed
188
     */
189
    public static function getIPN () {
190
        if (!self::isIPNRequestValid()) {
191
            return false;
192
        }
193
        return json_decode(file_get_contents('php://input'));
194
    }
195
}