PluginProbe
Ebook Store / 6.25
Ebook Store v6.25
6.25 6.24 6.23 6.22 6.21 6.20 trunk
ebook-store / payment_gateways / bitcoin / bp_lib.php

bp_lib.php in Ebook Store 6.25, at payment_gateways/bitcoin/bp_lib.php

306 lines 9.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * ©2011,2012,2013,2014 BITPAY, INC.
5 *
6 * Permission is hereby granted to any person obtaining a copy of this software
7 * and associated documentation for use and/or modification in association with
8 * the bitpay.com service.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16 * THE SOFTWARE.
17 *
18 * Bitcoin PHP payment library using the bitpay.com service.
19 *
20 * Version 1.1, [email protected]
21 *
22 */
23
24 require_once 'bp_options.php';
25
26 /**
27 *
28 * Writes $contents to a log file specified in the bp_options file or, if missing,
29 * defaults to a standard filename of 'bplog.txt'.
30 *
31 * @param mixed $contents
32 * @return
33 * @throws Exception $e
34 *
35 */
36 function bpLog($contents) {
37 try {
38 if(isset($bpOptions['logFile']) && $bpOptions['logFile'] != '') {
39 $file = dirname(__FILE__).$bpOptions['logFile'];
40 } else {
41 // Fallback to using a default logfile name in case the variable is
42 // missing or not set.
43 $file = dirname(__FILE__).'/bplog.txt';
44 }
45
46 file_put_contents($file, date('m-d H:i:s').": ", FILE_APPEND);
47
48 if (is_array($contents))
49 $contents = var_export($contents, true);
50 else if (is_object($contents))
51 $contents = json_encode($contents);
52
53 file_put_contents($file, $contents."\n", FILE_APPEND);
54
55 } catch (Exception $e) {
56 echo 'Error: ' . $e->getMessage();
57 }
58 }
59
60 /**
61 *
62 * Handles post/get to BitPay via curl.
63 *
64 * @param string $url, string $apiKey, boolean $post
65 * @return mixed $response
66 * @throws Exception $e
67 *
68 */
69 function bpCurl($url, $apiKey, $post = false) {
70 global $bpOptions;
71
72 if((isset($url) && trim($url) != '') && (isset($apiKey) && trim($apiKey) != '')) {
73 try {
74 $curl = curl_init();
75 $length = 0;
76
77 if ($post) {
78 curl_setopt($curl, CURLOPT_POST, 1);
79 curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
80 $length = strlen($post);
81 }
82
83 $uname = base64_encode($apiKey);
84
85 if($uname) {
86 $header = array(
87 'Content-Type: application/json',
88 'Content-Length: ' . $length,
89 'Authorization: Basic ' . $uname,
90 );
91
92 curl_setopt($curl, CURLOPT_URL, $url);
93 curl_setopt($curl, CURLOPT_PORT, 443);
94 curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
95 curl_setopt($curl, CURLOPT_TIMEOUT, 10);
96 curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ;
97 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1); // verify certificate
98 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // check existence of CN and verify that it matches hostname
99 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
100 curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
101 curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
102
103 $responseString = curl_exec($curl);
104
105 if($responseString == false) {
106 $response = array('error' => curl_error($curl));
107 if($bpOptions['useLogging'])
108 bpLog('Error: ' . curl_error($curl));
109 } else {
110 $response = json_decode($responseString, true);
111 if (!$response) {
112 $response = array('error' => 'invalid json: '.$responseString);
113 if($bpOptions['useLogging'])
114 bpLog('Error - Invalid JSON: ' . $responseString);
115 }
116 }
117
118 curl_close($curl);
119 return $response;
120 } else {
121 curl_close($curl);
122 if($bpOptions['useLogging'])
123 bpLog('Invalid data found in apiKey value passed to bpCurl. (Failed: base64_encode(apikey))');
124 return array('error' => 'Invalid data found in apiKey value passed to bpCurl. (Failed: base64_encode(apikey))');
125 }
126 } catch (Exception $e) {
127 @curl_close($curl);
128 if($bpOptions['useLogging'])
129 bpLog('Error: ' . $e->getMessage());
130 return array('error' => $e->getMessage());
131 }
132 } else {
133 // Invalid parameter specified
134 if($bpOptions['useLogging'])
135 bpLog('Error: You must supply non-empty url and apiKey parameters.');
136 return array('error' => 'You must supply non-empty url and apiKey parameters.');
137 }
138
139 }
140
141 /**
142 *
143 * Creates BitPay invoice via bpCurl.
144 *
145 * @param string $orderId, string $price, string $posData, array $options
146 * @return array $response
147 * @throws Exception $e
148 *
149 */
150 function bpCreateInvoice($orderId, $price, $posData, $options = array()) {
151 // $orderId: Used to display an orderID to the buyer. In the account summary view, this value is used to
152 // identify a ledger entry if present.
153 //
154 // $price: by default, $price is expressed in the currency you set in bp_options.php. The currency can be
155 // changed in $options.
156 //
157 // $posData: this field is included in status updates or requests to get an invoice. It is intended to be used by
158 // the merchant to uniquely identify an order associated with an invoice in their system. Aside from that, Bit-Pay does
159 // not use the data in this field. The data in this field can be anything that is meaningful to the merchant.
160 //
161 // $options keys can include any of:
162 // 'itemDesc', 'itemCode', 'notificationEmail', 'notificationURL', 'redirectURL', 'apiKey'
163 // 'currency', 'physical', 'fullNotifications', 'transactionSpeed', 'buyerName',
164 // 'buyerAddress1', 'buyerAddress2', 'buyerCity', 'buyerState', 'buyerZip', 'buyerEmail', 'buyerPhone'
165 //
166 // If a given option is not provided here, the value of that option will default to what is found in bp_options.php
167 // (see api documentation for information on these options).
168
169 global $bpOptions;
170
171 try {
172 $options = array_merge($bpOptions, $options); // $options override any options found in bp_options.php
173 $pos = array('posData' => $posData);
174
175 if ($bpOptions['verifyPos'])
176 $pos['hash'] = bpHash(serialize($posData), $options['apiKey']);
177
178 $options['posData'] = json_encode($pos);
179 $options['orderID'] = $orderId;
180 $options['price'] = $price;
181
182 $postOptions = array('orderID', 'itemDesc', 'itemCode', 'notificationEmail', 'notificationURL', 'redirectURL',
183 'posData', 'price', 'currency', 'physical', 'fullNotifications', 'transactionSpeed', 'buyerName',
184 'buyerAddress1', 'buyerAddress2', 'buyerCity', 'buyerState', 'buyerZip', 'buyerEmail', 'buyerPhone');
185
186 foreach($postOptions as $o) {
187 if (array_key_exists($o, $options))
188 $post[$o] = $options[$o];
189 }
190
191 $post = json_encode($post);
192
193 $response = bpCurl('https://bitpay.com/api/invoice/', $options['apiKey'], $post);
194
195 if($bpOptions['useLogging']) {
196 bpLog('Create Invoice: ');
197 bpLog($post);
198 bpLog('Response: ');
199 bpLog($response);
200 }
201
202 return $response;
203
204 } catch (Exception $e) {
205 if($bpOptions['useLogging'])
206 bpLog('Error: ' . $e->getMessage());
207 return array('error' => $e->getMessage());
208 }
209 }
210
211 /**
212 *
213 * Call from your notification handler to convert $_POST data to an object containing invoice data
214 *
215 * @param boolean $apiKey
216 * @return mixed $json
217 * @throws Exception $e
218 *
219 */
220 function bpVerifyNotification($apiKey = false) {
221 global $bpOptions;
222
223 try {
224 if (!$apiKey)
225 $apiKey = $bpOptions['apiKey'];
226
227 $post = file_get_contents("php://input");
228
229 if (!$post)
230 return 'No post data';
231
232 $json = json_decode($post, true);
233
234 if (is_string($json))
235 return $json; // error
236
237 if (!array_key_exists('posData', $json))
238 return 'no posData';
239
240 $posData = json_decode($json['posData'], true);
241
242 if($bpOptions['verifyPos'] and $posData['hash'] != bpHash(serialize($posData['posData']), $apiKey))
243 return 'authentication failed (bad hash)';
244
245 $json['posData'] = $posData['posData'];
246
247 return $json;
248 } catch (Exception $e) {
249 if($bpOptions['useLogging'])
250 bpLog('Error: ' . $e->getMessage());
251 return array('error' => $e->getMessage());
252 }
253 }
254
255 /**
256 *
257 * Retrieves an invoice from BitPay. $options can include 'apiKey'
258 *
259 * @param string $invoiceId, boolean $apiKey
260 * @return mixed $json
261 * @throws Exception $e
262 *
263 */
264 function bpGetInvoice($invoiceId, $apiKey=false) {
265 global $bpOptions;
266
267 try {
268 if (!$apiKey)
269 $apiKey = $bpOptions['apiKey'];
270
271 $response = bpCurl('https://bitpay.com/api/invoice/'.$invoiceId, $apiKey);
272
273 if (is_string($response))
274 return $response; // error
275
276 $response['posData'] = json_decode($response['posData'], true);
277 $response['posData'] = $response['posData']['posData'];
278
279 return $response;
280 } catch (Exception $e) {
281 if($bpOptions['useLogging'])
282 bpLog('Error: ' . $e->getMessage());
283 return 'Error: ' . $e->getMessage();
284 }
285 }
286
287 /**
288 *
289 * Generates a base64 encoded keyed hash.
290 *
291 * @param string $data, string $key
292 * @return string $hmac
293 * @throws Exception $e
294 *
295 */
296 function bpHash($data, $key) {
297 try {
298 $hmac = base64_encode(hash_hmac('sha256', $data, $key, TRUE));
299 return strtr($hmac, array('+' => '-', '/' => '_', '=' => ''));
300 } catch (Exception $e) {
301 if($bpOptions['useLogging'])
302 bpLog('Error: ' . $e->getMessage());
303 return 'Error: ' . $e->getMessage();
304 }
305 }
306