| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- <?php
- /**
- * BitPay - 更匿名、更安全、无需支付宝姓名和账户等个人私密信息
- *
- * Date: 2019/5/17
- * Time: 1:08 AM PST
- */
- namespace App\Services\Gateway;
- use App\Models\Paylist;
- use App\Services\Auth;
- use App\Services\Config;
- use App\Services\View;
- class BitPay extends AbstractPayment
- {
- private $bitpayAppSecret;
- private $bitpayGatewayUri;
- /*****************************************************************
- * BitPay Helper Function
- ******************************************************************/
- public function __construct($bitpayAppSecret)
- {
- $this->bitpayAppSecret = $bitpayAppSecret;
- $this->bitpayGatewayUri = 'https://api.mugglepay.com/v1/';
- }
- public function prepareSignId($tradeno)
- {
- $data_sign = array();
- $data_sign['merchant_order_id'] = $tradeno;
- $data_sign['secret'] = $this->bitpayAppSecret;
- ksort($data_sign);
- return http_build_query($data_sign);
- }
- public function sign($data)
- {
- return strtolower(md5(md5($data) . $this->bitpayAppSecret));
- }
- public function verify($data, $signature)
- {
- $mySign = $this->sign($data);
- return $mySign === $signature;
- }
- public function mprequest($data, $type = 'pay')
- {
- $headers = array('content-type: application/json', 'token: ' . $this->bitpayAppSecret);
- $curl = curl_init();
- if ($type === 'pay') {
- $this->bitpayGatewayUri .= 'orders';
- curl_setopt($curl, CURLOPT_URL, $this->bitpayGatewayUri);
- curl_setopt($curl, CURLOPT_POST, 1);
- $data_string = json_encode($data);
- curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
- } elseif ($type === 'query') {
- $this->bitpayGatewayUri .= 'orders/merchant_order_id/status?id=';
- $this->bitpayGatewayUri .= $data['merchant_order_id'];
- curl_setopt($curl, CURLOPT_URL, $this->bitpayGatewayUri);
- curl_setopt($curl, CURLOPT_HTTPGET, 1);
- }
- curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
- $data = curl_exec($curl);
- curl_close($curl);
- return $data;
- }
- public function query($tradeNo)
- {
- $data['merchant_order_id'] = $tradeNo;
- return json_decode($this->mprequest($data, 'query'), true);
- }
- /*****************************************************************
- * Abstract Payment Implentation
- ******************************************************************/
- public function purchase($request, $response, $args)
- {
- $price = $request->getParam('price');
- $type = $request->getParam('type');
- // file_put_contents(BASE_PATH.'/bitpay_purchase.log', $price . " " . $type . "\r\n", FILE_APPEND);
- if ($price <= 0) {
- return json_encode(['errcode' => -1, 'errmsg' => '非法的金额.']);
- }
- $user = Auth::getUser();
- $pl = new Paylist();
- $pl->userid = $user->id;
- $pl->total = $price;
- $pl->tradeno = self::generateGuid();
- $pl->save();
- $data['merchant_order_id'] = $pl->tradeno;
- $data['price_amount'] = (float)$price;
- $data['price_currency'] = 'CNY';
- $data['title'] = '支付单号' . $pl->tradeno;
- $data['description'] = '充值:' . $price;
- $data['description'] .= ' 元';
- $data['callback_url'] = Config::get('baseUrl') . '/payment/bitpay/notify';
- $data['success_url'] = Config::get('baseUrl') . '/user/payment/bitpay/return?merchantTradeNo=';
- $data['success_url'] .= $pl->tradeno;
- $data['cancel_url'] = $data['success_url'];
- if ($type === 'Alipay') {
- $data['checkout'] = 'QBIT';
- }
- $str_to_sign = $this->prepareSignId($pl->tradeno);
- $data['token'] = $this->sign($str_to_sign);
- $result = json_decode($this->mprequest($data), true);
- $result['pid'] = $pl->tradeno;
- // file_put_contents(BASE_PATH.'/bitpay_purchase.log', json_encode($data)."\r\n", FILE_APPEND);
- // file_put_contents(BASE_PATH.'/bitpay_purchase.log', json_encode($result)."\r\n", FILE_APPEND);
- if ($result['status'] == 200 || $result['status'] == 201) {
- $result['payment_url'] .= '&lang=zh';
- return json_encode(array('url' => $result['payment_url'], 'errcode' => 0, 'pid' => $pl->id));
- }
- return json_encode(['errcode' => -1, 'errmsg' => $result . error]);
- }
- public function notify($request, $response, $args)
- {
- if (!$this->bitpayAppSecret || $this->bitpayAppSecret === '') {
- $return = [];
- $return['status'] = 400;
- echo json_encode($return);
- return;
- }
- $inputString = file_get_contents('php://input', 'r');
- $inputStripped = str_replace(array("\r", "\n", "\t", "\v"), '', $inputString);
- $inputJSON = json_decode($inputStripped, true); //convert JSON into array
- $data = array();
- if ($inputJSON !== null) {
- $data['status'] = $inputJSON['status'];
- $data['order_id'] = $inputJSON['order_id'];
- $data['merchant_order_id'] = $inputJSON['merchant_order_id'];
- $data['price_amount'] = $inputJSON['price_amount'];
- $data['price_currency'] = $inputJSON['price_currency'];
- $data['created_at_t'] = $inputJSON['created_at_t'];
- }
- // file_put_contents(BASE_PATH.'/bitpay_notify.log', json_encode($data)."\r\n", FILE_APPEND);
- // 准备待签名数据
- $str_to_sign = $this->prepareSignId($inputJSON['merchant_order_id']);
- $resultVerify = $this->verify($str_to_sign, $inputJSON['token']);
- $isPaid = $data !== null && $data['status'] !== null && $data['status'] === 'PAID';
- // file_put_contents(BASE_PATH.'/bitpay_notify.log', $resultVerify."\r\n".$isPaid."\r\n", FILE_APPEND);
- if ($resultVerify && $isPaid) {
- $this->postPayment($data['merchant_order_id'], 'BitPay');
- // echo 'SUCCESS';
- $return = [];
- $return['status'] = 200;
- echo json_encode($return);
- } else {
- // echo 'FAIL';
- $return = [];
- $return['status'] = 400;
- echo json_encode($return);
- }
- }
- public function getPurchaseHTML()
- {
- return View::getSmarty()->fetch('user/bitpay.tpl');
- }
- public function getReturnHTML($request, $response, $args)
- {
- $pid = $_GET['merchantTradeNo'];
- $p = Paylist::where('tradeno', '=', $pid)->first();
- $money = $p->total;
- if ($p->status == 1) {
- $success = 1;
- } else {
- $data = $this->query($pid);
- $isPaid = $data !== null && $data['order'] !== null && $data['order']['status'] !== null && $data['order']['status'] === 'PAID';
- // file_put_contents(BASE_PATH.'/bitpay_return.log', $pid . " " . $data ."\r\n". $isPaid . "\r\n", FILE_APPEND);
- if ($isPaid) {
- $this->postPayment($pid, 'BitPay');
- $success = 1;
- } else {
- $success = 0;
- }
- }
- return View::getSmarty()->assign('money', $money)->assign('success', $success)->fetch('user/pay_success.tpl');
- }
- public function getStatus($request, $response, $args)
- {
- $return = [];
- $p = Paylist::where('tradeno', $_POST['pid'])->first();
- $return['ret'] = 1;
- $return['result'] = $p->status;
- // file_put_contents(BASE_PATH.'/bitpay_status_success.log', json_encode($return)."\r\n", FILE_APPEND);
- return json_encode($return);
- }
- }
|