1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @package Blockchain payment |
4
|
|
|
* @category modules |
5
|
|
|
* @author Nazar Mokrynskyi <[email protected]> |
6
|
|
|
* @copyright Copyright (c) 2015-2016, Nazar Mokrynskyi |
7
|
|
|
* @license MIT License, see license.txt |
8
|
|
|
*/ |
9
|
|
|
namespace cs\modules\Blockchain_payment; |
10
|
|
|
use |
11
|
|
|
cs\Config, |
12
|
|
|
cs\CRUD_helpers, |
13
|
|
|
cs\Singleton; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* @method static $this instance($check = false) |
17
|
|
|
*/ |
18
|
|
|
class Transactions { |
19
|
|
|
use CRUD_helpers { |
20
|
|
|
search as public; |
21
|
|
|
} |
22
|
|
|
use |
23
|
|
|
Singleton; |
24
|
|
|
|
25
|
|
|
protected $data_model = [ |
26
|
|
|
'id' => 'int', |
27
|
|
|
'amount' => 'float:0', |
28
|
|
|
'currency' => 'text', |
29
|
|
|
'user' => 'int:0', |
30
|
|
|
'module' => 'text', |
31
|
|
|
'purpose' => 'text', |
32
|
|
|
'description' => 'text', |
33
|
|
|
'amount_btc' => 'float:0.0005', |
34
|
|
|
'destination_address' => 'text', |
35
|
|
|
'input_address' => 'text', |
36
|
|
|
'created' => 'int:0', |
37
|
|
|
'paid' => 'int:0', |
38
|
|
|
'confirmed' => 'int:0', |
39
|
|
|
'secret' => 'text', |
40
|
|
|
'transaction_hash' => 'text', |
41
|
|
|
'input_transaction_hash' => 'text' |
42
|
|
|
]; |
43
|
|
|
protected $table = '[prefix]blockchain_payment_transactions'; |
44
|
|
|
protected $blockchain_url = 'https://blockchain.info'; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Returns database index |
48
|
|
|
* |
49
|
|
|
* @return int |
50
|
|
|
*/ |
51
|
|
|
protected function cdb () { |
52
|
|
|
return Config::instance()->module('Blockchain_payment')->db('transactions'); |
53
|
|
|
} |
54
|
|
|
/** |
55
|
|
|
* Get transaction |
56
|
|
|
* |
57
|
|
|
* @param int|int[] $id |
58
|
|
|
* |
59
|
|
|
* @return array|false |
|
|
|
|
60
|
|
|
*/ |
61
|
|
|
function get ($id) { |
62
|
|
|
return $this->read($id); |
63
|
|
|
} |
64
|
|
|
/** |
65
|
|
|
* Add new transaction |
66
|
|
|
* |
67
|
|
|
* @param float $amount |
68
|
|
|
* @param string $currency |
69
|
|
|
* @param int $user |
70
|
|
|
* @param string $module |
71
|
|
|
* @param string $purpose |
72
|
|
|
* @param string $description |
73
|
|
|
* |
74
|
|
|
* @return false|int Id of created transaction on success of <b>false</> on failure |
|
|
|
|
75
|
|
|
* |
76
|
|
|
*/ |
77
|
|
|
function add ($amount, $currency, $user, $module, $purpose, $description) { |
78
|
|
|
while ($secret = hash('sha512', random_bytes(1000))) { |
79
|
|
|
if ($this->search(['secret' => $secret, 'total_count' => true])) { |
80
|
|
|
break; |
81
|
|
|
} |
82
|
|
|
} |
83
|
|
|
$amount_btc = $currency == 'BTC' ? $amount : $this->convert_to_btc($amount, $currency); |
84
|
|
|
// Minimal acceptable payment |
85
|
|
|
if ($amount_btc < 0.0005) { |
86
|
|
|
$amount_btc = 0.0005; |
87
|
|
|
} |
88
|
|
|
$Config = Config::instance(); |
89
|
|
|
$destination_address = $Config->module('Blockchain_payment')->bitcoin_address; |
90
|
|
|
$callback = $Config->base_url()."/Blockchain_payment?secret=$secret"; |
91
|
|
|
$blockchain_receive = file_get_json( |
92
|
|
|
"$this->blockchain_url/api/receive?method=create&address=$destination_address&callback=".urlencode($callback) |
93
|
|
|
); |
94
|
|
|
if ( |
95
|
|
|
!isset($blockchain_receive['callback_url']) || |
96
|
|
|
$blockchain_receive['callback_url'] !== $callback |
97
|
|
|
) { |
98
|
|
|
return false; |
99
|
|
|
} |
100
|
|
|
$input_address = $blockchain_receive['input_address']; |
101
|
|
|
return $this->create( |
102
|
|
|
$amount, |
103
|
|
|
$currency, |
104
|
|
|
$user, |
105
|
|
|
$module, |
106
|
|
|
$purpose, |
107
|
|
|
$description, |
108
|
|
|
$amount_btc, |
109
|
|
|
$destination_address, |
110
|
|
|
$input_address, |
111
|
|
|
time(), |
112
|
|
|
0, |
113
|
|
|
0, |
114
|
|
|
$secret, |
115
|
|
|
'', |
116
|
|
|
'' |
117
|
|
|
); |
118
|
|
|
} |
119
|
|
|
/** |
120
|
|
|
* Convert any supported currency to BTC (external API call) |
121
|
|
|
* |
122
|
|
|
* @param float $amount |
123
|
|
|
* @param string $currency |
124
|
|
|
* |
125
|
|
|
* @return float |
126
|
|
|
*/ |
127
|
|
|
function convert_to_btc ($amount, $currency) { |
128
|
|
|
return (float)file_get_contents("$this->blockchain_url/tobtc?currency=$currency&value=$amount"); |
129
|
|
|
} |
130
|
|
|
/** |
131
|
|
|
* Set transaction as paid (not confirmed though) and set transaction hashed |
132
|
|
|
* |
133
|
|
|
* @param int $id |
134
|
|
|
* @param string $transaction_hash |
135
|
|
|
* @param string $input_transaction_hash |
136
|
|
|
* |
137
|
|
|
* @return bool |
138
|
|
|
*/ |
139
|
|
|
function set_as_paid ($id, $transaction_hash, $input_transaction_hash) { |
140
|
|
|
$data = $this->get($id); |
141
|
|
|
$data['paid'] = time(); |
142
|
|
|
$data['transaction_hash'] = $transaction_hash; |
143
|
|
|
$data['input_transaction_hash'] = $input_transaction_hash; |
144
|
|
|
return $this->update($data); |
145
|
|
|
} |
146
|
|
|
/** |
147
|
|
|
* Set transaction as confirmed (each paid transaction should be confirmed in order to be completed) |
148
|
|
|
* |
149
|
|
|
* @param int $id |
150
|
|
|
* |
151
|
|
|
* @return bool |
152
|
|
|
*/ |
153
|
|
|
function set_as_confirmed ($id) { |
154
|
|
|
$data = $this->get($id); |
155
|
|
|
$data['confirmed'] = time(); |
156
|
|
|
return $this->update($data); |
157
|
|
|
} |
158
|
|
|
/** |
159
|
|
|
* Delete specified order |
160
|
|
|
* |
161
|
|
|
* @param int $id |
162
|
|
|
* |
163
|
|
|
* @return bool |
164
|
|
|
*/ |
165
|
|
|
function del ($id) { |
166
|
|
|
return $this->delete($id); |
167
|
|
|
} |
168
|
|
|
} |
169
|
|
|
|
This check compares the return type specified in the
@return
annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.If the return type contains the type array, this check recommends the use of a more specific type like
String[]
orarray<String>
.