From d17e3819d7c033cbc815a65ab9fbb758bc2ebb8b Mon Sep 17 00:00:00 2001 From: yanzai Date: Sun, 22 Sep 2024 01:25:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=AF=B9=E6=8E=A5=E5=B0=8F?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Http/Controllers/API/ApiMapController.php | 3 + .../Http/Controllers/API/H5/PayController.php | 70 ++++++++++++--- .../Http/Controllers/API/XCXApiController.php | 90 ++++++++++--------- Laravel/routes/web.php | 3 + 4 files changed, 109 insertions(+), 57 deletions(-) diff --git a/Laravel/app/Http/Controllers/API/ApiMapController.php b/Laravel/app/Http/Controllers/API/ApiMapController.php index 8859946..ee85ec8 100644 --- a/Laravel/app/Http/Controllers/API/ApiMapController.php +++ b/Laravel/app/Http/Controllers/API/ApiMapController.php @@ -50,6 +50,9 @@ class ApiMapController extends Controller 'GetReportList' => $base_url . '/api/H5/GetReportList',//获取关联的所有体检人报告列表 'GetReportJieLunJianYi' => $base_url . '/api/H5/GetReportJieLunJianYi',//获取报告结论建议页面数据 'GetReportDetaiList' => $base_url . '/api/H5/GetReportDetaiList',//完整报告中的列表 + 'StartPay' => $base_url . '/api/H5/StartPay',//开始支付 + 'CheckPay' => $base_url . '/api/H5/CheckPay',//支付查询 + 'Refund' => $base_url . '/api/H5/Refund',//退款 ]; } diff --git a/Laravel/app/Http/Controllers/API/H5/PayController.php b/Laravel/app/Http/Controllers/API/H5/PayController.php index 3e560b3..aa7927c 100644 --- a/Laravel/app/Http/Controllers/API/H5/PayController.php +++ b/Laravel/app/Http/Controllers/API/H5/PayController.php @@ -29,48 +29,92 @@ class PayController extends Controller } + //对参数进行签名,返回前端需要的参数,前端携带参数跳转小程序支付 public function StartPay() { + $openid = request('openid'); $id = request('id'); $orderInfo = DB::table('orders')->where(['id' => $id,])->first(); if (!$orderInfo) return \Yz::echoError1("未找到有效订单"); if ($orderInfo->status !== 1) return \Yz::echoError1("订单不是待支付状态不能支付。当前状态:" . $orderInfo->status); $personInfo = DB::table('web_user_person')->where(['id' => $orderInfo->person_id, 'is_del' => 0])->first(); if (!$personInfo) return \Yz::echoError1("就诊人异常"); - + $sub_org_code=0; //小程序端医院代码 + if($orderInfo->hospital_id==1){ + $sub_org_code=6; + } + if($orderInfo->hospital_id==2){ + $sub_org_code=2; + } + if($sub_org_code==0) return \Yz::echoError1("医院id异常"); + $XCXApi=new XCXApiController(); $params = [ - 'appId' => "1111111111111111", + 'appid' =>$XCXApi::$appid, + 'sub_org_code'=>$sub_org_code, 'ghzid' => $personInfo->ghzid, 'orderid' => $orderInfo->order_number, 'order_desc' => $orderInfo->title, - 'amount' => $orderInfo->true_price * 100, - 'timestamp' => (string)time(), - 'nonce' => self::nonce(), + 'amount' => (int)($orderInfo->true_price * 100), + 'notify_url'=>$XCXApi::$pay_notify_url ]; - //签名规则? - $params['sign'] = ''; - $params['notify_url'] = ''; - $XCX = new XCXApiController(); - $data = $XCX::Post('订单支付', $params); + $nonce=self::nonce(); + $timestamp=(string)time(); + + //签名 + $base64Signature=$XCXApi::Sign('/pages/other/entry/index?path=/pages/physical-examination/payment/index',$params,$nonce,$timestamp,true); + $params['timestamp']=$timestamp; + $params['nonce']=$nonce; + $params['signature']=$base64Signature; + return \Yz::Return(true,"操作完成",['info'=>$params]); } //订单支付查询 public function CheckPay() { + $openid = request('openid'); $order_number= request('order_number'); $XCX = new XCXApiController(); - $data = $XCX::Post('订单查询', ['orderid'=>$order_number]); + $res = $XCX::Post('订单查询', ['orderid'=>$order_number]); //判断如果支付成功,更改订单状态 - if($data['trade_state']==='SUCCESS'){ + if($res['trade_state']==='SUCCESS'){ DB::table('orders')->where(['order_number'=>$order_number])->update([ 'status'=>2 ]); + return \Yz::Return(true,"支付成功",[]); + }else{ + return \Yz::echoError1("支付失败".$res['trade_state']); } } //退款 public function Refund() { - $order_number= request('order_number'); + //先调用思信取消,恢复号源,然后再退款 + //判断订单状态是否是已经支付,判断是否到检, + $openid = request('openid'); + $id= request('id'); + $orderInfo = DB::table('orders')->where(['id' => $id,])->first(); + if (!$orderInfo) return \Yz::echoError1("未找到有效订单"); + if ($orderInfo->status !==2) return \Yz::echoError1("订单状态异常。当前状态:" . $orderInfo->status); + if ($orderInfo->check_status ==2) return \Yz::echoError1("已登记体检,禁止退款"); + //调用思信取消,恢复号源 + + //退款 + $data=[ + 'orderid'=>$orderInfo->order_number, + 'refund_order_id'=>'T'.$orderInfo->order_number, + 'refund_amount'=>(int)($orderInfo->true_price * 100), + ]; + $XCX = new XCXApiController(); + $res = $XCX::Post('订单退款', $data); + if($res['refund_state']==='SUCCESS'){ + DB::table('orders')->where(['id'=>$id])->update([ + 'status'=>5 + ]); + return \Yz::Return(true,"退款成功",[]); + }else{ + return \Yz::echoError1("退款失败".$res['refund_state']); + } + } public static function nonce($l = 16) diff --git a/Laravel/app/Http/Controllers/API/XCXApiController.php b/Laravel/app/Http/Controllers/API/XCXApiController.php index 8302a28..dd3db79 100644 --- a/Laravel/app/Http/Controllers/API/XCXApiController.php +++ b/Laravel/app/Http/Controllers/API/XCXApiController.php @@ -8,59 +8,40 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Schema; +use Illuminate\Support\Facades\Storage; class XCXApiController extends Controller { public static $request; - public static $appid = "13a159e438a742dd932c9bddbfaa41e5"; - public static $signType = "OPENAPI-SHA256-RSA2048"; - public static $privateKey = "-----BEGIN PRIVATE KEY-----\n" - . "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDGr/KoMftpabe/Mxqm0q6d8GYnNabPiMlPnr - 3zQEGzeFSyNp5G8ZD5p6o6taj5Kmg6JPndR0WmNTXr0o5VD6vs3DfbV8wFfHKJDtPYijzUCHXWcef1XyMGOiBFf -ToLVYn+mCoD9dnOy+jBqWg6bQSTOTfX+Uo9/qcxbY5bDv+aPZ7gJYnW6IFN5f/vnw6oPVXehIHhHtv+6/KdLVK -s2aguSlMv9moVlG2MN8Fr0sg4n5szfIT/Kwh7m344WP5eMpYgQuqeJe7sKRKlRqE1SRb8zFGTXviaFEJqH8uDoHD -fw89q786E0NjFHvpcMPoufIRq0dz/5NqC1c/by5zQk+RXAgMBAAECggEBAKbESAik60EvWutBGb2sWKR4g0Wl4 -r2PMmmB9C2YYY0iEvUCoxco62ahNGDS2WFKFvG214LDr9IyF3A46v66iLPmo3uX1cdFDV289FNstGHEOCQmt2t -czykK4MtysKWSxqDLV3i7gnXw8QycBMAFgTGRdS3yMD6Y3/y82B/WFvR+B7GgchnBHVMM266D2iXOhS7v6XY -Wjdu1yVRfmyDSw3gI/2FYxVIi/Xb69KlTOjegtVx28/NjCET+quB+BY5osZpHODD5gPX3ltuj7FowaAfaJiUzHoZ8TX -Q8kpXmK2XwResjIBnEcXJMwlruKwZf70j1dmIDQHStLojn90JMdQECgYEA+Y6dCDkG/1RQVZacLGQtZndCdTJ1t -HBs8cGmjlNcpbVo9If8vm6NUbuHYxWDI9pafWjtBLs69II0rwTlgOCFVthCls5F9sChgn0rYgwZskmKqpQvQNyXTP -gHndRLaqyJ7Kk3i2lYObxvpXQgTNxjlHgpQkyvCO5QprfYZgx8b9MCgYEAy9Eff2jsa7EC6Cwv96p7QhFhNcHfMgu -TO8i4b3YEXIVU+X0fKxSY1Rq9RUxL5wkb8/TyT17JOqg0snZs6M6f/jAO1gH611W1q3gaUOQ/naAI/wOJWj7tTa42 -hvQFC82IA/zzCOR/RUalQfUX8lNjACOh5+HaXjOn/nIHw7/Bau0CgYEAl/URBYrECgFrEVKuMhGl23jPDNH2/jJfBC -6ono2AIp7+E7giXEqw3o3T+K+GtPQmmaqkeHcRhQUr006l+P29842nrnBYBdJyBiT1n7RCiV9igk/NHi+0KXf2G1 -LDwWbibSr02X0B7dYiHZtCd8rTD/rDFM3g3w1OKtZTfIAp3WUCgYAIFfvR6i+29gbPfzFH+hN5w4a/wzk/mwX0UT -o/8caqhP+iBjy+UMrfaXgoz6YTPGFHhGg4jeId2Z59lgUsF0ZxpyZvhxSUhmn2q4UfwG5lqnuw4ksIsYZolojDQdsRZ -M4Imnhp2ebSsMLNoxOYIYbD8qXxtRwcsJ/xkESOl4Ts4QKBgQDYMuU0lCiml1/z8VTpAX91O8gK61vczHZZarhJN -URYZLJgZCnJZXgS/f0BUIYdvhMHLdrHsGPS3HXHEn0oKJyZERbtSGM1UVK9It/Pb+IlWhAZYkajIlM+p5gn8SYorE -27sNjRqoKRKYyy4BfhVGvFSI+Ofyo1yPzhrnRTiSjBjQ==\n" - . "-----END PRIVATE KEY-----"; + public static $appid = "13a159e438a742dd932c9bddbfaa41e5";//appid + public static $signType = "OPENAPI-SHA256-RSA2048";//签名认证类型 + public static $baseUrl = "https://xdfe-api.hnxdfe.com/hisminitest"; + public static $pay_notify_url = "https://www.xxxxxxxx.com";//支付完成后小程序跳转H5路径 public static function Api($url_code) { - $url = 'https://xdfe-api.hnxdfe.com/hisminitest'; - // $url = 'https://dqgatjzx-wx.sixinyun.com'; - $api['就诊人列表'] = "{$url}/jeecg-boot/hospital/openapi/archive/list"; - $api['订单支付'] = "{$url}/PEISCommon/QueryGroups"; - $api['订单查询'] = "{$url}/PEISCommon/QueryGroups/460107000001"; - $api['订单退款'] = "{$url}/PEISCommon/QueryCombos"; + $api['就诊人列表'] = "/jeecg-boot/hospital/openapi/archive/list"; + $api['订单查询'] = "/jeecg-boot/hospital/openapi/order/query"; + $api['订单退款'] = "/jeecg-boot/hospital/openapi/order/refund"; return $api["{$url_code}"] ?? $url_code; } public static function Post($url_code, $data) { - $url = self::Api($url_code); - self::RequestLog($url, $data, $url_code, '小程序接口'); - $body_str = self::buildSortedQueryString($data); + $url_address = self::Api($url_code); + self::RequestLog(self::$baseUrl.$url_address, $data, $url_code, '小程序接口'); + $timestamp = time(); + $nonce = md5(uniqid(rand(), true)); + $base64Signature = self::Sign( $url_address, $data, $nonce, $timestamp); $response = Http::withHeaders([ - 'Authorization' => self::BuildAuthorization('POST', "/jeecg-boot/hospital/openapi/archive/list", $body_str) - ])->post($url, $data); - + 'Authorization' => self::BuildAuthorization($nonce, $timestamp, $base64Signature) + ])->post(self::$baseUrl.$url_address, $data); + // dd($response); if ($response->successful()) { // 处理成功的响应 $res_string = json_encode($response->json(), JSON_UNESCAPED_UNICODE); - dd($res_string); + // dd($res_string); $str_len = mb_strlen($res_string, 'utf-8'); $str_size = $str_len / 1024; $save_res = $res_string; @@ -119,28 +100,49 @@ URYZLJgZCnJZXgS/f0BUIYdvhMHLdrHsGPS3HXHEn0oKJyZERbtSGM1UVK9It/Pb+IlWhAZYkajIlM+p ksort($params); // 2. 拼接参数名和参数值 $queryString = http_build_query($params, '', '&', PHP_QUERY_RFC3986); + return $queryString; } //计算签名和 Authorization - public static function BuildAuthorization($method, $url, $body) + public static function Sign($url, $data, $nonce, $timestamp,$is_urlencode=false) { - $currentTimestamp = time(); - $nonce = md5(uniqid(rand(), true)); - $SignStr = $method . '\n' . $url . '\n' . $currentTimestamp . '\n' . $nonce . '\n' . $body . '\n'; + $body = self::buildSortedQueryString($data); + $method = 'POST'; - // 生成 SHA-256 哈希值 - // $hashedData = hash('sha256', $SignStr, true); // true 表示返回二进制格式 + // $method = 'POST'; + // $url = '/jeecg-boot/hospital/openapi/archive/list'; + // $timestamp = "1726880312"; + // $nonce = '88e5928d0c34aa0e9cb0bade72f83a67'; + // $body = 'wxid=oosgJj-SVIxTrm_g1p213tsSHK5g'; + + $private_key = Storage::get('keys/private_key.pem'); + $SignStr = $method . "\n" . + $url . "\n" . + $timestamp . "\n" . + $nonce . "\n" . + $body; +//dd($SignStr); // 使用私钥进行 RSA 签名 - openssl_sign($SignStr, $signature, self::$privateKey, OPENSSL_ALGO_SHA256); + openssl_sign($SignStr, $signature, $private_key, OPENSSL_ALGO_SHA256); + if($is_urlencode){ + $signature= urlencode($signature); + } // 对签名结果进行 Base64 编码 $base64Signature = base64_encode($signature); + // dd($base64Signature); + return $base64Signature; + } - $signInfo = 'appid=' . self::$appid . ',nonce=' . $nonce . ',timestamp=' . $currentTimestamp . ',signature=' . $base64Signature; + //构建Authorization + public static function BuildAuthorization($nonce, $currentTimestamp, $base64Signature) + { + $signInfo = "appid=\"" . self::$appid . "\",nonce=\"" . $nonce . "\",timestamp=\"" . $currentTimestamp . "\",signature=\"" . $base64Signature . "\""; +//dd($signInfo); return self::$signType . ' ' . $signInfo; } diff --git a/Laravel/routes/web.php b/Laravel/routes/web.php index 6d32598..95f20f8 100644 --- a/Laravel/routes/web.php +++ b/Laravel/routes/web.php @@ -60,6 +60,9 @@ Route::group(['prefix' => 'api/H5'], function () { Route::post('/GetReportJieLunJianYi', 'App\Http\Controllers\API\H5\ReportController@GetReportJieLunJianYi');//获取报告结论建议页面数据 Route::post('/GetReportDetaiList', 'App\Http\Controllers\API\H5\ReportController@GetReportDetaiList');//完整报告中的列表 Route::post('/GetReportDetai', 'App\Http\Controllers\API\H5\ReportController@GetReportDetai');//完整报告某项详情 + Route::post('/StartPay', 'App\Http\Controllers\API\H5\PayController@StartPay');//开始支付接口 + Route::post('/CheckPay', 'App\Http\Controllers\API\H5\PayController@CheckPay');//支付结果查询接口 + Route::post('/Refund', 'App\Http\Controllers\API\H5\PayController@Refund');//退款