From d635a5a34388634ef37f6b284ee9438ee5e2c46e Mon Sep 17 00:00:00 2001 From: "iVampireSP.com" Date: Wed, 28 Dec 2022 00:24:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Console/Commands/TestCommand.php | 45 ++++ .../Controllers/Web/BalanceController.php | 249 ++++++++++++++---- app/Http/Middleware/VerifyCsrfToken.php | 3 +- app/Jobs/CheckAndChargeBalance.php | 3 +- app/Models/Balance.php | 81 +++--- composer.json | 1 + composer.lock | 189 ++++++++++++- config/pay.php | 34 +-- resources/views/balances/index.blade.php | 25 +- resources/views/balances/pay.blade.php | 89 ++++++- resources/views/contact.blade.php | 30 +++ resources/views/layouts/app.blade.php | 10 +- routes/web.php | 26 +- 13 files changed, 645 insertions(+), 140 deletions(-) create mode 100644 app/Console/Commands/TestCommand.php create mode 100644 resources/views/contact.blade.php diff --git a/app/Console/Commands/TestCommand.php b/app/Console/Commands/TestCommand.php new file mode 100644 index 0000000..8a58c90 --- /dev/null +++ b/app/Console/Commands/TestCommand.php @@ -0,0 +1,45 @@ +selectRaw('sum(amount) as amount') + ->where('created_at', '>=', today()) + ->toSql(); + + + dd($sql); + + + return CommandAlias::SUCCESS; + } +} diff --git a/app/Http/Controllers/Web/BalanceController.php b/app/Http/Controllers/Web/BalanceController.php index b8142c0..caff6ea 100644 --- a/app/Http/Controllers/Web/BalanceController.php +++ b/app/Http/Controllers/Web/BalanceController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Web; +use App\Exceptions\ChargeException; use App\Http\Controllers\Controller; use App\Models\Balance; use App\Models\Module; @@ -9,8 +10,13 @@ use Illuminate\Contracts\View\View; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Http; +use Illuminate\Support\Facades\Log; use Illuminate\Validation\ValidationException; +use SimpleSoftwareIO\QrCode\Facades\QrCode; use Yansongda\LaravelPay\Facades\Pay; +use Yansongda\Pay\Exception\ContainerException; +use Yansongda\Pay\Exception\InvalidParamsException; class BalanceController extends Controller { @@ -30,26 +36,19 @@ public function store(Request $request) // 充值 $this->validate($request, [ 'amount' => 'required|integer|min:0.1|max:10000', + 'payment' => 'required|in:wechat,alipay', ]); $user = $request->user(); $balance = new Balance(); - $data = [ 'user_id' => $user->id, 'amount' => $request->input('amount'), - 'payment' => 'alipay', + 'payment' => $request->input('payment'), ]; - // if local - // if (env('APP_ENV') == 'local') { - // $data['payment'] = null; - // $data['paid_at'] = now(); - // } - - $balance = $balance->create($data); // 生成 18 位订单号 @@ -58,82 +57,220 @@ public function store(Request $request) $balance->save(); - // $balances['pay_url'] = route('balances.balances.show', ['balances' => $balances['order_id']]); - - return redirect()->route('balances.balances.show', ['balances' => $balance->order_id]); + return redirect()->route('balances.show', compact('balance')); } /** + * 显示充值页面和状态(ajax) */ - public function show(Balance $balance) + public function show(Request $request, Balance $balance) { + if ($balance->paid_at !== null) { - return $this->error('订单已支付'); + if ($request->ajax()) { + return $this->success($balance); + } + + return view('balances.process', compact('balance')); + } else { + if ($request->ajax()) { + return $this->success($balance); + } } + if (now()->diffInDays($balance->created_at) > 1) { - return $this->error('订单已失效'); + if ($request->ajax()) { + return $this->forbidden($balance); + } + + return redirect()->route('index')->with('error', '订单已逾期。'); } - $web = Pay::alipay()->web([ - 'out_trade_no' => $balance->order_id, - 'total_amount' => $balance->amount, - 'subject' => config('app.display_name') . ' 充值', - ]); + $balance->load('user'); - return view('balances.pay', ['html' => (string)$web->getBody()]); + $subject = config('app.display_name') . ' 充值'; + + $order = [ + 'out_trade_no' => $balance->order_id, + ]; + + $code = QrCode::size(150); + + if ($balance->payment === 'wechat') { + $pay = $this->xunhu_wechat($balance, $subject); + + $qr_code = $code->generate($pay['url']); + } else { + $order['subject'] = $subject; + $order['total_amount'] = $balance->amount; + + $pay = Pay::alipay()->scan($order); + + $qr_code = $code->generate($pay->qr_code); + } + + if (!isset($qr_code)) { + abort(500, '支付方式错误'); + } + + return view('balances.pay', compact('balance', 'qr_code')); + } + + private function xunhu_wechat(Balance $balance, $subject = '支付') + { + $data = [ + 'version' => '1.1', + 'lang' => 'zh-cn', + 'plugins' => config('app.name'), + 'appid' => config('pay.xunhu.app_id'), + 'trade_order_id' => $balance->order_id, + 'payment' => 'wechat', + 'type' => 'WAP', + 'wap_url' => config('app.url'), + 'wap_name' => config('app.display_name'), + 'total_fee' => $balance->amount, + 'title' => $subject, + 'time' => time(), + 'notify_url' => route('balances.notify', 'wechat'), + 'return_url' => route('balances.notify', 'wechat'), + 'callback_url' => route('balances.show', $balance), + 'modal' => null, + 'nonce_str' => str_shuffle(time()), + ]; + + $data['hash'] = $this->xunhu_hash($data); + + $response = Http::post(config('pay.xunhu.gateway'), $data); + + if (!$response->successful()) { + abort(500, '支付网关错误'); + } + + $response = $response->json(); + + $hash = $this->xunhu_hash($response); + + if (!isset($response['hash']) || $response['hash'] !== $hash) { + abort(500, '无法校验支付网关返回数据'); + } + + return $response; + } + + private function xunhu_hash(array $arr) + { + ksort($arr); + + $pre = []; + foreach ($arr as $key => $data) { + if (is_null($data) || $data === '') { + continue; + } + if ($key == 'hash') { + continue; + } + $pre[$key] = stripslashes($data); + } + + $arg = ''; + $qty = count($pre); + $index = 0; + + foreach ($pre as $key => $val) { + $arg .= "$key=$val"; + if ($index++ < ($qty - 1)) { + $arg .= "&"; + } + } + + return md5($arg . config('pay.xunhu.app_secret')); } /** * @throws ValidationException */ - public function notify(Request $request): View|JsonResponse + public function notify(Request $request, $payment): View|JsonResponse { - $this->validate($request, [ - 'out_trade_no' => 'required', - ]); + $is_paid = false; + // $pay_amount = 0; + + if ($payment === 'alipay') { + $out_trade_no = $request->input('out_trade_no'); + } else if ($payment === 'wechat') { + $out_trade_no = $request->input('trade_order_id'); + } else { + abort(400, '支付方式错误'); + } // 检测订单是否存在 - $balance = Balance::where('order_id', $request->out_trade_no)->with('user')->first(); + $balance = Balance::where('order_id', $out_trade_no)->with('user')->first(); if (!$balance) { abort(404, '找不到订单。'); } // 检测订单是否已支付 - // if ($balance->paid_at !== null) { - // // return $this->success('订单已支付'); - // return view('balances.process', compact('balance')); - // } + if ($balance->paid_at !== null) { + if ($request->ajax()) { + return $this->success($balance); + } + return view('balances.process', compact('balance')); + } + + + // 处理验证 + if ($payment === 'alipay') { + try { + $pay = Pay::alipay()->callback(); + + } catch (ContainerException|InvalidParamsException $e) { + abort(500, $e->getMessage()); + } + + $is_paid = true; + } else if ($payment === 'wechat') { + if (!($request->filled('hash') || $request->filled('trade_order_id'))) { + return $this->error('参数错误。'); + } + + if ($request->filled('plugins') && $request->input('plugins') != config('app.name')) { + return $this->error('插件不匹配。'); + } + + $hash = $this->xunhu_hash($request->toArray()); + if ($request->input('hash') != $hash) { + Log::debug('hash error', $request->toArray()); + } + + if ($request->input('status') === 'OD') { + $is_paid = true; + } + + } else { + abort(400, '支付方式错误。'); + } + + if ($is_paid) { + try { + (new Transaction)->addAmount($balance->user_id, 'alipay', $balance->amount); + + $balance->update([ + 'paid_at' => now() + ]); + + } catch (ChargeException $e) { + abort(500, $e->getMessage()); + } + } + + + if ($request->ajax()) { + return $this->success($balance); + } return view('balances.process', compact('balance')); - // try { - // $data = Pay::alipay()->callback(); - // } catch (InvalidResponseException $e) { - // return $this->error('支付失败'); - // } - - // // 检测 out_trade_no 是否为商户系统中创建的订单号 - // if ($data->out_trade_no != $balances->order_id) { - // return $this->error('订单号不一致'); - // } - - // if ((int) $data->total_amount != (int) $balances->amount) { - // throw new ChargeException('金额不一致'); - // } - - // // 验证 商户 - // if ($data['app_id'] != config('balances.alipay.default.app_id')) { - // throw new ChargeException('商户不匹配'); - // } - - // - // if ((new \App\Jobs\CheckAndChargeBalance())->checkAndCharge($balance, true)) { - // return view('pay_process'); - // } else { - // abort(500, '支付失败'); - // } } /** diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 9e86521..3c9f4a7 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -12,6 +12,7 @@ class VerifyCsrfToken extends Middleware * @var array */ protected $except = [ - // + // notify + 'balances/notify/*', ]; } diff --git a/app/Jobs/CheckAndChargeBalance.php b/app/Jobs/CheckAndChargeBalance.php index 2b2b7e9..a5a39c4 100644 --- a/app/Jobs/CheckAndChargeBalance.php +++ b/app/Jobs/CheckAndChargeBalance.php @@ -7,7 +7,6 @@ use App\Models\Transaction; use Illuminate\Support\Facades\Log; use Yansongda\LaravelPay\Facades\Pay; -use Yansongda\Pay\Exception\InvalidResponseException; class CheckAndChargeBalance extends Job { @@ -62,7 +61,7 @@ public function checkAndCharge(Balance $balance, $check = false): bool $balance->update([ 'paid_at' => now() ]); - } catch (InvalidResponseException|ChargeException $e) { + } catch (ChargeException $e) { Log::error($e->getMessage()); return false; } diff --git a/app/Models/Balance.php b/app/Models/Balance.php index 40b1588..0294b02 100644 --- a/app/Models/Balance.php +++ b/app/Models/Balance.php @@ -2,10 +2,12 @@ namespace App\Models; +use Eloquent; +use GeneaLabs\LaravelModelCaching\CachedBuilder; use GeneaLabs\LaravelModelCaching\Traits\Cachable; -use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo as BelongsToAlias; +use Illuminate\Support\Carbon; use function auth; /** @@ -19,47 +21,47 @@ * @property string $remaining_amount * @property string|null $paid_at * @property int|null $user_id - * @property \Illuminate\Support\Carbon|null $created_at - * @property \Illuminate\Support\Carbon|null $updated_at - * @property-read \App\Models\User|null $user - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance all($columns = []) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance avg($column) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance cache(array $tags = []) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance cachedValue(array $arguments, string $cacheKey) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance count($columns = '*') - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance disableCache() - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance disableModelCaching() - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance exists() - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance flushCache(array $tags = []) + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * @property-read User|null $user + * @method static CachedBuilder|Balance all($columns = []) + * @method static CachedBuilder|Balance avg($column) + * @method static CachedBuilder|Balance cache(array $tags = []) + * @method static CachedBuilder|Balance cachedValue(array $arguments, string $cacheKey) + * @method static CachedBuilder|Balance count($columns = '*') + * @method static CachedBuilder|Balance disableCache() + * @method static CachedBuilder|Balance disableModelCaching() + * @method static CachedBuilder|Balance exists() + * @method static CachedBuilder|Balance flushCache(array $tags = []) * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance * getModelCacheCooldown(\Illuminate\Database\Eloquent\Model $instance) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance inRandomOrder($seed = '') - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance insert(array $values) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance isCachable() - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance max($column) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance min($column) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance newModelQuery() - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance newQuery() - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance query() - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance sum($column) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance thisUser() - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance truncate() - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance whereAmount($value) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance whereCreatedAt($value) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance whereId($value) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance whereOrderId($value) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance wherePaidAt($value) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance wherePayment($value) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance whereRemainingAmount($value) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance whereTradeId($value) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance whereUpdatedAt($value) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance whereUserId($value) - * @method static \GeneaLabs\LaravelModelCaching\CachedBuilder|Balance withCacheCooldownSeconds(?int $seconds = null) - * @mixin \Eloquent + * @method static CachedBuilder|Balance inRandomOrder($seed = '') + * @method static CachedBuilder|Balance insert(array $values) + * @method static CachedBuilder|Balance isCachable() + * @method static CachedBuilder|Balance max($column) + * @method static CachedBuilder|Balance min($column) + * @method static CachedBuilder|Balance newModelQuery() + * @method static CachedBuilder|Balance newQuery() + * @method static CachedBuilder|Balance query() + * @method static CachedBuilder|Balance sum($column) + * @method static CachedBuilder|Balance thisUser() + * @method static CachedBuilder|Balance truncate() + * @method static CachedBuilder|Balance whereAmount($value) + * @method static CachedBuilder|Balance whereCreatedAt($value) + * @method static CachedBuilder|Balance whereId($value) + * @method static CachedBuilder|Balance whereOrderId($value) + * @method static CachedBuilder|Balance wherePaidAt($value) + * @method static CachedBuilder|Balance wherePayment($value) + * @method static CachedBuilder|Balance whereRemainingAmount($value) + * @method static CachedBuilder|Balance whereTradeId($value) + * @method static CachedBuilder|Balance whereUpdatedAt($value) + * @method static CachedBuilder|Balance whereUserId($value) + * @method static CachedBuilder|Balance withCacheCooldownSeconds(?int $seconds = null) + * @mixin Eloquent */ class Balance extends Model { - use HasFactory, Cachable; + use Cachable; protected $fillable = [ 'order_id', @@ -70,6 +72,11 @@ class Balance extends Model 'trade_id' ]; + protected $casts = [ + 'paid_at' => 'datetime', + 'amount' => 'decimal:2', + ]; + // route key public function getRouteKeyName(): string { diff --git a/composer.json b/composer.json index 17f61ec..1ba7f42 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,7 @@ "laravel/tinker": "^2.7", "php-mqtt/laravel-client": "^1.1", "pusher/pusher-php-server": "^7.2", + "simplesoftwareio/simple-qrcode": "^4.2", "spiral/roadrunner": "^2.8.2", "symfony/psr-http-message-bridge": "^2.1", "yansongda/laravel-pay": "~3.2.0" diff --git a/composer.lock b/composer.lock index b98cec0..a4c105c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,68 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4753398c786d748ab94e8601f781d93a", + "content-hash": "3bd5ef4c5c796cdfc149a5ef57641d9a", "packages": [ + { + "name": "bacon/bacon-qr-code", + "version": "2.0.8", + "source": { + "type": "git", + "url": "https://github.com/Bacon/BaconQrCode.git", + "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/8674e51bb65af933a5ffaf1c308a660387c35c22", + "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "dasprid/enum": "^1.0.3", + "ext-iconv": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phly/keep-a-changelog": "^2.1", + "phpunit/phpunit": "^7 | ^8 | ^9", + "spatie/phpunit-snapshot-assertions": "^4.2.9", + "squizlabs/php_codesniffer": "^3.4" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "type": "library", + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "BaconQrCode is a QR code generator for PHP.", + "homepage": "https://github.com/Bacon/BaconQrCode", + "support": { + "issues": "https://github.com/Bacon/BaconQrCode/issues", + "source": "https://github.com/Bacon/BaconQrCode/tree/2.0.8" + }, + "time": "2022-12-07T17:46:57+00:00" + }, { "name": "brick/math", "version": "0.10.1", @@ -155,6 +215,59 @@ ], "time": "2022-04-01T19:23:25+00:00" }, + { + "name": "dasprid/enum", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/DASPRiD/Enum.git", + "reference": "5abf82f213618696dda8e3bf6f64dd042d8542b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/5abf82f213618696dda8e3bf6f64dd042d8542b2", + "reference": "5abf82f213618696dda8e3bf6f64dd042d8542b2", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require-dev": { + "phpunit/phpunit": "^7 | ^8 | ^9", + "squizlabs/php_codesniffer": "^3.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "PHP 7.1 enum implementation", + "keywords": [ + "enum", + "map" + ], + "support": { + "issues": "https://github.com/DASPRiD/Enum/issues", + "source": "https://github.com/DASPRiD/Enum/tree/1.0.3" + }, + "time": "2020-10-02T16:03:48+00:00" + }, { "name": "dflydev/dot-access-data", "version": "v3.0.1", @@ -4608,6 +4721,80 @@ ], "time": "2022-11-05T23:03:38+00:00" }, + { + "name": "simplesoftwareio/simple-qrcode", + "version": "4.2.0", + "source": { + "type": "git", + "url": "https://github.com/SimpleSoftwareIO/simple-qrcode.git", + "reference": "916db7948ca6772d54bb617259c768c9cdc8d537" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SimpleSoftwareIO/simple-qrcode/zipball/916db7948ca6772d54bb617259c768c9cdc8d537", + "reference": "916db7948ca6772d54bb617259c768c9cdc8d537", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "bacon/bacon-qr-code": "^2.0", + "ext-gd": "*", + "php": ">=7.2|^8.0" + }, + "require-dev": { + "mockery/mockery": "~1", + "phpunit/phpunit": "~9" + }, + "suggest": { + "ext-imagick": "Allows the generation of PNG QrCodes.", + "illuminate/support": "Allows for use within Laravel." + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "SimpleSoftwareIO\\QrCode\\QrCodeServiceProvider" + ], + "aliases": { + "QrCode": "SimpleSoftwareIO\\QrCode\\Facades\\QrCode" + } + } + }, + "autoload": { + "psr-4": { + "SimpleSoftwareIO\\QrCode\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Simple Software LLC", + "email": "support@simplesoftware.io" + } + ], + "description": "Simple QrCode is a QR code generator made for Laravel.", + "homepage": "https://www.simplesoftware.io/#/docs/simple-qrcode", + "keywords": [ + "Simple", + "generator", + "laravel", + "qrcode", + "wrapper" + ], + "support": { + "issues": "https://github.com/SimpleSoftwareIO/simple-qrcode/issues", + "source": "https://github.com/SimpleSoftwareIO/simple-qrcode/tree/4.2.0" + }, + "time": "2021-02-08T20:43:55+00:00" + }, { "name": "spiral/core", "version": "3.4.0", diff --git a/config/pay.php b/config/pay.php index db8f43e..e85957e 100644 --- a/config/pay.php +++ b/config/pay.php @@ -4,20 +4,23 @@ use Yansongda\Pay\Pay; -$secret_file = env('ALIPAY_APP_SECERT_CERT_PATH', config_path('secrets/alipayAppPriv.key')); -if (!file_exists($secret_file)) { - $secret_file = ''; +$alipay_app_private_key = env('ALIPAY_APP_SECERT_CERT_PATH', config_path('secrets/alipayAppPriv.key')); +if (!file_exists($alipay_app_private_key)) { + $alipay_app_private_key = ''; } else { - $secret_file = trim(file_get_contents($secret_file)); + $alipay_app_private_key = trim(file_get_contents($alipay_app_private_key)); } +$wechat_pay_cert = env('WECHAT_PAY_CERT_PATH', config_path('secrets/wepay_cert.pem')); +$wechat_pay_private_key = env('WECHAT_PAY_PRIVATE_KEY_PATH', config_path('secrets/wepay_key.pem')); + return [ 'alipay' => [ 'default' => [ // 必填-支付宝分配的 app_id 'app_id' => env('ALIPAY_APP_ID'), // 必填-应用私钥 字符串或路径 - 'app_secret_cert' => $secret_file, + 'app_secret_cert' => $alipay_app_private_key, // 必填-应用公钥证书 路径 'app_public_cert_path' => env('ALIPAY_APP_PUBLIC_CERT_PATH', config_path('secrets/appCertPublicKey.crt')), // 必填-支付宝公钥证书 路径 @@ -36,17 +39,17 @@ 'wechat' => [ 'default' => [ // 必填-商户号,服务商模式下为服务商商户号 - 'mch_id' => env('WECHAT_MENCENT_ID'), + 'mch_id' => env('WECHAT_MERCHANT_ID'), // 必填-商户秘钥 - 'mch_secret_key' => '', + 'mch_secret_key' => env('WECHAT_V3_API_KEY'), // 必填-商户私钥 字符串或路径 - 'mch_secret_cert' => '', + 'mch_secret_cert' => $wechat_pay_private_key, // 必填-商户公钥证书路径 - 'mch_public_cert_path' => '', + 'mch_public_cert_path' => $wechat_pay_cert, // 必填 - 'notify_url' => '', + 'notify_url' => env('WECHAT_PAY_CALLBACK_NOTIFY_URL'), // 选填-公众号 的 app_id - 'mp_app_id' => '', + 'mp_app_id' => env('WECHAT_MP_APP_ID'), // 选填-小程序 的 app_id 'mini_app_id' => '', // 选填-app 的 app_id @@ -63,10 +66,6 @@ 'sub_mini_app_id' => '', // 选填-服务商模式下,子商户id 'sub_mch_id' => '', - // 选填-微信公钥证书路径, optional,强烈建议 php-fpm 模式下配置此参数 - 'wechat_public_cert_path' => [ - '45F59D4DABF31918AFCEC556D5D2C6E376675D57' => __DIR__ . '/Cert/wechatPublicKey.crt', - ], // 选填-默认为正常模式。可选为: MODE_NORMAL, MODE_SERVICE 'mode' => Pay::MODE_NORMAL, ], @@ -87,6 +86,11 @@ 'notify_url' => '', ], ], + 'xunhu' => [ + 'app_id' => env('XUNHU_PAY_APP_ID'), + 'app_secret' => env('XUNHU_PAY_APP_SECRET'), + 'gateway' => env('XUNHU_PAY_GATEWAY', 'https://api.xunhupay.com/payment/do.html'), + ], 'http' => [ // optional 'timeout' => 5.0, 'connect_timeout' => 5.0, diff --git a/resources/views/balances/index.blade.php b/resources/views/balances/index.blade.php index 162600c..9b5479f 100644 --- a/resources/views/balances/index.blade.php +++ b/resources/views/balances/index.blade.php @@ -3,16 +3,31 @@ @section('title', '余额') @section('content') -

余额

-

您的余额: {{ $balance }} 元 余额不可用于提现

+

余额 {{ $balance }}

+

余额不可用于提现

充值余额

-
@csrf - 元 - + + 微信支付 + 支付宝 + + +
+ + + + + + + + + +
diff --git a/resources/views/balances/pay.blade.php b/resources/views/balances/pay.blade.php index 5ae1086..0e75a37 100644 --- a/resources/views/balances/pay.blade.php +++ b/resources/views/balances/pay.blade.php @@ -1,13 +1,82 @@ - - +@extends('layouts.app') - - - 支付订单 - +@section('title', '付款') - -{!! $html !!} - +@section('content') - +

莱云 支付处理器

+

此页面正在进行充值交易。

+ +
+

您将要给 {{ $balance->user->name }} 充值 {{ $balance->amount }} 元。 + @if ($balance->user == auth()->user()) + 这是您自己的账号。 + @else + 但是请看仔细,这不是您自己的账号。 + @endif + +

+ +

如果您已知晓情况,请 + @php + if ($balance->payment === 'alipay') { + $payment = '支付宝'; + } elseif ($balance->payment === 'wechat') { + $payment = '微信'; + } else { + $payment = '相应的软件'; + } + + @endphp + 使用"{{ $payment }}"扫描二维码。 +

+ + + {{ $qr_code }} +
+ +

您已成功完成支付。@auth + 我们将稍后带您去余额界面。 + @else + 您可以关闭此网页去通知 {{ $balance->user->name }} 了。 + @endauth

+

此支付出现了问题。@auth + 我们将稍后带您去余额界面。稍后请尽快联系我们。 + @else + 您可以让 {{ $balance->user->name }} 联系我们,或者您可以点击上方的"联系我们"按钮。 + @endauth

+ + + + +@endsection diff --git a/resources/views/contact.blade.php b/resources/views/contact.blade.php new file mode 100644 index 0000000..e4103b3 --- /dev/null +++ b/resources/views/contact.blade.php @@ -0,0 +1,30 @@ +@extends('layouts.app') + +@section('content') + +

请注意,我们官方的控制面板只有一个,那就是 + dash.laecloud.com。 +
+ 莱云 官方没有推出过任何其它形式的客户端(比如桌面客户端等)。我们不会其它形式的客户端做出任何技术支持,也不解答任何问题,也不负责任何损失。 +

+ + @auth +

你好, {{ auth()->user()->name }}。 +
+ 如果您在使用一些服务方面遇到了问题,可以在"仪表盘"的菜单中的"工单",联系我们。 +
+ "工单"是我们的客户支持系统,您可以在这里提交工单,我们会尽快处理。 +
+ "工单"会根据您的服务,将您的工单投递到不同的部门,交给他们进行处理。 +

+ + @endauth + +

+ 您可以加入我们的 QQ 群: 769779712。 +
+ 请注意,我们不会在群里给任何不看《提问的智慧》的人解答问题。并且我们还会快速的把他们踢出群。 +

+ +@endsection diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 48a878e..6d3d8e9 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -39,10 +39,10 @@