diff --git a/app/Components/Helpers.php b/app/Components/Helpers.php index 5c8a36b6..3ed11ca0 100644 --- a/app/Components/Helpers.php +++ b/app/Components/Helpers.php @@ -105,7 +105,7 @@ class Helpers $data[$vo->name] = $vo->value; } - $data['is_onlinePay'] = ($data['is_AliPay'] || $data['is_QQPay'] || $data['is_WeChatPay'])? : 0; + $data['is_onlinePay'] = ($data['is_AliPay'] || $data['is_QQPay'] || $data['is_WeChatPay'] || $data['is_otherPay'])? : 0; return $data; } diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php index 6b7ad6be..6283c1ce 100644 --- a/app/Http/Controllers/AdminController.php +++ b/app/Http/Controllers/AdminController.php @@ -1991,7 +1991,7 @@ EOF; } // 支付设置判断 - if(in_array($name, ['is_AliPay', 'is_QQPay', 'is_WeChatPay']) && $value != ''){ + if(in_array($name, ['is_AliPay', 'is_QQPay', 'is_WeChatPay', 'is_otherPay']) && $value != ''){ switch($value){ case 'f2fpay': if(!self::$systemConfig['f2fpay_app_id'] || !self::$systemConfig['f2fpay_private_key'] || !self::$systemConfig['f2fpay_public_key']){ @@ -2008,6 +2008,11 @@ EOF; return Response::json(['status' => 'fail', 'message' => '请先设置【PayJs】必要参数']); } break; + case 'bitpayx': + if(!self::$systemConfig['bitpayx']){ + return Response::json(['status' => 'fail', 'message' => '请先设置【麻瓜宝】必要参数']); + } + break; default: return Response::json(['status' => 'fail', 'message' => '未知支付渠道']); break; diff --git a/app/Http/Controllers/Gateway/AopF2F.php b/app/Http/Controllers/Gateway/AopF2F.php index fbdf4749..e800911a 100644 --- a/app/Http/Controllers/Gateway/AopF2F.php +++ b/app/Http/Controllers/Gateway/AopF2F.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Gateway; use App\Http\Models\Payment; use Auth; use Exception; +use Log; use Omnipay\Alipay\Responses\AopCompletePurchaseResponse; use Omnipay\Alipay\Responses\AopTradePreCreateResponse; use Omnipay\Omnipay; @@ -67,6 +68,7 @@ class AopF2F extends AbstractPayment exit('success'); } }catch(Exception $e){ + Log::error('支付宝当面付 '.$e); exit('fail'); } } diff --git a/app/Http/Controllers/Gateway/BitpayX.php b/app/Http/Controllers/Gateway/BitpayX.php new file mode 100644 index 00000000..3006bce2 --- /dev/null +++ b/app/Http/Controllers/Gateway/BitpayX.php @@ -0,0 +1,148 @@ +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='.$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; + } + + /** + * @param Request $request + * + * @return mixed + */ + public function purchase(Request $request) + { + $payment = new Payment(); + $payment->sn = self::generateGuid(); + $payment->user_id = Auth::user()->id; + $payment->oid = $request->input('oid'); + $payment->amount = $request->input('amount'); + $payment->save(); + + $data = [ + 'merchant_order_id' => $payment->sn, + 'price_amount' => (float)$request->input('amount'), + 'price_currency' => 'CNY', + 'pay_currency' => $request->input('type') == 1? 'ALIPAY' : 'WECHAT', + 'title' => '支付单号:'.$payment->sn, + 'description' => parent::$systemConfig['subject_name']? : parent::$systemConfig['website_name'], + 'callback_url' => (parent::$systemConfig['website_callback_url']? : parent::$systemConfig['website_url']).'/payment/notify', + 'success_url' => parent::$systemConfig['website_url'].'/invoices', + 'cancel_url' => parent::$systemConfig['website_url'], + 'token' => $this->sign($this->prepareSignId($payment->sn)), + + ]; + + $result = json_decode($this->mprequest($data), TRUE); + + + if($result['status'] === 200 || $result['status'] === 201){ + $result['payment_url'] .= '&lang=zh'; + + return Response::json(['status' => 'success', 'url' => $result['payment_url'] .= '&lang=zh', 'message' => '创建订单成功!']); + } + + return Response::json(['status' => 'fail', 'data' => $result, 'message' => '创建订单失败!']); + } + + public function sign($data) + { + return strtolower(md5(md5($data).parent::$systemConfig['bitpay_secret'])); + } + + public function prepareSignId($tradeno) + { + $data_sign = [ + 'merchant_order_id' => $tradeno, + 'secret' => parent::$systemConfig['bitpay_secret'], + 'type' => 'FIAT', + ]; + ksort($data_sign); + + return http_build_query($data_sign); + } + + public function notify(Request $request) + { + $inputString = file_get_contents('php://input', 'r'); + $inputStripped = str_replace(["\r", "\n", "\t", "\v"], '', $inputString); + $inputJSON = json_decode($inputStripped, TRUE); //convert JSON into array + $data = []; + if($inputJSON !== NULL){ + $data = [ + 'status' => $inputJSON['status'], + 'order_id' => $inputJSON['order_id'], + 'merchant_order_id' => $inputJSON['merchant_order_id'], + 'price_amount' => $inputJSON['price_amount'], + 'price_currency' => $inputJSON['price_currency'], + 'created_at_t' => $inputJSON['created_at_t'], + ]; + } + // 准备待签名数据 + $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'; + + if($resultVerify && $isPaid){ + $this->postPayment($inputJSON['merchant_order_id'], 'BitPayX'); + $return = []; + $return['status'] = 200; + echo json_encode($return); + }else{ + $return = []; + $return['status'] = 400; + echo json_encode($return); + } + exit(); + } + + public function verify($data, $signature) + { + $mySign = $this->sign($data); + + return $mySign === $signature; + } + + public function getReturnHTML(Request $request) + { + // TODO: Implement getReturnHTML() method. + } + + public function getPurchaseHTML() + { + // TODO: Implement getPurchaseHTML() method. + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Gateway/CodePay.php b/app/Http/Controllers/Gateway/CodePay.php index 0914a08b..0e60e61d 100644 --- a/app/Http/Controllers/Gateway/CodePay.php +++ b/app/Http/Controllers/Gateway/CodePay.php @@ -21,7 +21,7 @@ class CodePay extends AbstractPayment $data = [ 'id' => parent::$systemConfig['codepay_id'], 'pay_id' => $payment->sn, - 'type' => $request->input('method'),//1支付宝支付 2QQ钱包 3微信支付 + 'type' => $request->input('type'),//1支付宝支付 2QQ钱包 3微信支付 'price' => $payment->amount, 'page' => 4, 'outTime' => 900, diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php index 5f08f07c..86b88559 100644 --- a/app/Http/Controllers/PaymentController.php +++ b/app/Http/Controllers/PaymentController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers; use App\Components\Helpers; use App\Http\Controllers\Gateway\AopF2F; +use App\Http\Controllers\Gateway\BitpayX; use App\Http\Controllers\Gateway\CodePay; use App\Http\Controllers\Gateway\PayJs; use App\Http\Models\Coupon; @@ -36,6 +37,8 @@ class PaymentController extends Controller return new Codepay(); case 'payjs': return new PayJs(); + case 'bitpayx': + return new BitpayX(); default: return NULL; } @@ -69,7 +72,7 @@ class PaymentController extends Controller } // 创建支付订单 - public function purchase(Request $request) + public static function purchase(Request $request) { $goods_id = $request->input('goods_id'); $coupon_sn = $request->input('coupon_sn'); @@ -173,16 +176,16 @@ class PaymentController extends Controller User::query()->where('id', Auth::user()->id)->decrement('balance', $amount*100); // 记录余额操作日志 - $this->addUserBalanceLog(Auth::user()->id, $order->oid, Auth::user()->balance, Auth::user()->balance-$amount, -1*$amount, '购买商品:'.$goods->name); + (new Controller)->addUserBalanceLog(Auth::user()->id, $order->oid, Auth::user()->balance, Auth::user()->balance-$amount, -1*$amount, '购买商品:'.$goods->name); $order = Order::query()->where('oid', $orderSn)->first(); $order->status = 2; $order->save(); User::query()->where('id', $order->user_id)->increment('balance', $order->amount*100); // 余额变动记录日志 - $this->addUserBalanceLog($order->user_id, $order->oid, $order->user->balance, $order->user->balance+$order->amount, $order->amount, '用户在线充值'); + (new Controller)->addUserBalanceLog($order->user_id, $order->oid, $order->user->balance, $order->user->balance+$order->amount, $order->amount, '用户在线充值'); }else{ - $request->merge(['oid' => $order->oid, 'amount' => $amount]); + $request->merge(['oid' => $order->oid, 'amount' => $amount, 'type' => $request->input('pay_type')]); return self::getClient()->purchase($request); } diff --git a/public/assets/images/bitcoin.svg b/public/assets/images/bitcoin.svg new file mode 100644 index 00000000..11af6f7a --- /dev/null +++ b/public/assets/images/bitcoin.svg @@ -0,0 +1,78 @@ + + + + diff --git a/resources/views/admin/system.blade.php b/resources/views/admin/system.blade.php index 2036d014..8a70c0f7 100644 --- a/resources/views/admin/system.blade.php +++ b/resources/views/admin/system.blade.php @@ -1017,6 +1017,15 @@ +