@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\API\WeChatPayController;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DemoController extends Controller
|
||||
{
|
||||
public function pay_back()
|
||||
{
|
||||
$input = file_get_contents('php://input');
|
||||
file_put_contents(base_path() . '/storage/app/pay/pay_back.txt', urldecode($input));
|
||||
return [
|
||||
'code' => 'SUCCESS',
|
||||
'message' => '成功',
|
||||
];
|
||||
}
|
||||
|
||||
public function pay(Request $request)
|
||||
{
|
||||
$openid = $request->post('openid');
|
||||
$total = $request->post('total');
|
||||
$wcp = new WeChatPayController();
|
||||
$wcp->builder([
|
||||
'appid' => 'wx0d92d2990ec16a55',
|
||||
'pem_path' => base_path() . '/storage/app/pay/key.pem',
|
||||
'cer_path' => base_path() . '/storage/app/pay/crt.pem',
|
||||
'cer_num' => '3CE37188EBCFBBEB800B0E1C69B360F05A3E80CD',
|
||||
'mchid' => '1638739772',
|
||||
'v3' => 'AVPV7NxK8cC2RvRrrwdTqUG9YbQXQe3w',
|
||||
]);
|
||||
$out_trade_no = date('Ymd') . time() . rand(10, 99);
|
||||
$pay = $wcp->create([
|
||||
'description' => '体检预约',
|
||||
'out_trade_no' => $out_trade_no,
|
||||
'notify_url' => 'https://api.hainan2024.sa0.online/api/Demo/pay_back',
|
||||
'total' => $total,
|
||||
'openid' => $openid
|
||||
]);
|
||||
|
||||
return \Yz::Return(true, '获取成功', [
|
||||
'pay' => $pay
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\API;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use WeChatPay\Builder;
|
||||
use WeChatPay\Crypto\AesGcm;
|
||||
use WeChatPay\Crypto\Rsa;
|
||||
use WeChatPay\Formatter;
|
||||
use WeChatPay\Util\PemUtil;
|
||||
|
||||
class WeChatPayController extends Controller
|
||||
{
|
||||
public static $mp_instance = false;
|
||||
public static $mp_config = false;
|
||||
|
||||
public function callback($input, $header, $apiv3Key, $pem)
|
||||
{
|
||||
$inWechatpaySignature = $header['wechatpay-signature'][0];
|
||||
$inWechatpayTimestamp = $header['wechatpay-timestamp'][0];
|
||||
$inWechatpaySerial = $header['wechatpay-serial'][0];
|
||||
$inWechatpayNonce = $header['wechatpay-nonce'][0];
|
||||
$inBody = $input;
|
||||
$platformPublicKeyInstance = Rsa::from($pem, Rsa::KEY_TYPE_PUBLIC);
|
||||
$timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);
|
||||
// $verifiedStatus = Rsa::verify(
|
||||
// Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody),
|
||||
// $inWechatpaySignature,
|
||||
// $platformPublicKeyInstance
|
||||
// );
|
||||
// if ($timeOffsetStatus && $verifiedStatus) {
|
||||
if ($timeOffsetStatus) {
|
||||
$inBodyArray = (array)json_decode($inBody, true);
|
||||
['resource' => [
|
||||
'ciphertext' => $ciphertext,
|
||||
'nonce' => $nonce,
|
||||
'associated_data' => $aad
|
||||
]] = $inBodyArray;
|
||||
$inBodyResource = AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $aad);
|
||||
return (array)json_decode($inBodyResource, true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function builder($config)
|
||||
{
|
||||
self::$mp_config = $config;
|
||||
$merchantPrivateKeyFilePath = 'file://' . self::$mp_config['pem_path'];
|
||||
$platformCertificateFilePath = 'file://' . self::$mp_config['cer_path'];
|
||||
$merchantId = self::$mp_config['mchid'];
|
||||
$merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
|
||||
self::$mp_config['pem_key'] = $merchantPrivateKeyInstance;
|
||||
$merchantCertificateSerial = self::$mp_config['cer_num'];
|
||||
$platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
|
||||
$platformCertificateSerial = self::$mp_config['v3'];
|
||||
self::$mp_instance = Builder::factory([
|
||||
'mchid' => $merchantId,
|
||||
'serial' => $merchantCertificateSerial,
|
||||
'privateKey' => $merchantPrivateKeyInstance,
|
||||
'certs' => [
|
||||
$platformCertificateSerial => $platformPublicKeyInstance,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function refund($config)
|
||||
{
|
||||
$res = false;
|
||||
try {
|
||||
$resp = self::$mp_instance
|
||||
->v3->refund->domestic->refunds
|
||||
->post([
|
||||
'json' => [
|
||||
'transaction_id' => $config['transaction_id'],
|
||||
'out_refund_no' => $config['out_refund_no'],
|
||||
'amount' => [
|
||||
'refund' => $config['total'],
|
||||
'total' => $config['total'],
|
||||
'currency' => 'CNY',
|
||||
],
|
||||
],
|
||||
]);
|
||||
$res = json_decode($resp->getBody(), true);
|
||||
} catch (\Exception $e) {
|
||||
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
|
||||
$r = $e->getResponse();
|
||||
$res = json_decode($r->getBody(), true);
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function create($config)
|
||||
{
|
||||
$res = false;
|
||||
try {
|
||||
$post_data = [
|
||||
'appid' => self::$mp_config['appid'],
|
||||
'mchid' => self::$mp_config['mchid'],
|
||||
'description' => $config['description'],
|
||||
'out_trade_no' => $config['out_trade_no'],
|
||||
'notify_url' => $config['notify_url'],
|
||||
'amount' => [
|
||||
'total' => $config['total'],
|
||||
],
|
||||
'payer' => [
|
||||
'openid' => $config['openid']
|
||||
]
|
||||
];
|
||||
$resp = self::$mp_instance
|
||||
->v3->pay->transactions->jsapi
|
||||
->post([
|
||||
'json' => $post_data,
|
||||
]);
|
||||
$res = json_decode($resp->getBody(), true);
|
||||
} catch (\Exception $e) {
|
||||
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
|
||||
$r = $e->getResponse();
|
||||
$res = json_decode($r->getBody(), true);
|
||||
}
|
||||
}
|
||||
$params = [
|
||||
'appId' => self::$mp_config['appid'],
|
||||
'timeStamp' => (string)time(),
|
||||
'nonceStr' => self::nonce(),
|
||||
'package' => 'prepay_id=' . $res['prepay_id'],
|
||||
];
|
||||
$params += ['paySign' => Rsa::sign(
|
||||
Formatter::joinedByLineFeed(...array_values($params)),
|
||||
self::$mp_config['pem_key']
|
||||
), 'signType' => 'RSA'];
|
||||
return [
|
||||
'appid' => $params['appId'],
|
||||
'timestamp' => $params['timeStamp'],
|
||||
'nonce_str' => $params['nonceStr'],
|
||||
'package' => $params['package'],
|
||||
'pay_sign' => $params['paySign'],
|
||||
'sign_type' => $params['signType'],
|
||||
];
|
||||
}
|
||||
|
||||
public function check($out_trade_no)
|
||||
{
|
||||
$res = false;
|
||||
try {
|
||||
$resp = self::$mp_instance
|
||||
->v3->pay->transactions->outTradeNo->_out_trade_no_
|
||||
->get([
|
||||
'query' => ['mchid' => self::$mp_config['mchid']],
|
||||
'out_trade_no' => (string)$out_trade_no,
|
||||
]);
|
||||
$res = json_decode($resp->getBody(), true);
|
||||
} catch (\Exception $e) {
|
||||
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
|
||||
$r = $e->getResponse();
|
||||
$res = json_decode($r->getBody(), true);
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function nonce($l = 16)
|
||||
{
|
||||
$charts = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz0123456789";
|
||||
$max = strlen($charts) - 1;
|
||||
$noncestr = "";
|
||||
for ($i = 0; $i < $l; $i++) {
|
||||
$noncestr .= $charts[rand(0, $max)];
|
||||
}
|
||||
return $noncestr;
|
||||
}
|
||||
}
|
||||
@ -1,65 +1,69 @@
|
||||
{
|
||||
"name": "laravel/laravel",
|
||||
"type": "project",
|
||||
"description": "The Laravel Framework.",
|
||||
"keywords": ["framework", "laravel"],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"fruitcake/laravel-cors": "^2.0",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"laravel/framework": "^8.75",
|
||||
"laravel/sanctum": "^2.11",
|
||||
"laravel/tinker": "^2.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"facade/ignition": "^2.5",
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
"laravel/sail": "^1.0.1",
|
||||
"mockery/mockery": "^1.4.4",
|
||||
"nunomaduro/collision": "^5.10",
|
||||
"phpunit/phpunit": "^9.5.10"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"app/Lib"
|
||||
],
|
||||
"psr-4": {
|
||||
"App\\": "app/",
|
||||
"Database\\Factories\\": "database/factories/",
|
||||
"Database\\Seeders\\": "database/seeders/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php artisan package:discover --ansi"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
|
||||
],
|
||||
"post-root-package-install": [
|
||||
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||
],
|
||||
"post-create-project-cmd": [
|
||||
"@php artisan key:generate --ansi"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"dont-discover": []
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
"name": "laravel/laravel",
|
||||
"type": "project",
|
||||
"description": "The Laravel Framework.",
|
||||
"keywords": [
|
||||
"framework",
|
||||
"laravel"
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"fruitcake/laravel-cors": "^2.0",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"laravel/framework": "^8.75",
|
||||
"laravel/sanctum": "^2.11",
|
||||
"laravel/tinker": "^2.5",
|
||||
"wechatpay/wechatpay": "^1.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"facade/ignition": "^2.5",
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
"laravel/sail": "^1.0.1",
|
||||
"mockery/mockery": "^1.4.4",
|
||||
"nunomaduro/collision": "^5.10",
|
||||
"phpunit/phpunit": "^9.5.10"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"app/Lib"
|
||||
],
|
||||
"psr-4": {
|
||||
"App\\": "app/",
|
||||
"Database\\Factories\\": "database/factories/",
|
||||
"Database\\Seeders\\": "database/seeders/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php artisan package:discover --ansi"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
|
||||
],
|
||||
"post-root-package-install": [
|
||||
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||
],
|
||||
"post-create-project-cmd": [
|
||||
"@php artisan key:generate --ansi"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"dont-discover": []
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
||||
|
||||
@ -0,0 +1 @@
|
||||
import{$ as a,g as t,e,s as i,f as n,h as o}from"./index-DqaBDANc.js";const s=a.token;function l(){return t(s)}const d=e("counter",{state:()=>({api_map:{},count:0,loading:0}),actions:{loadingStart(){this.loading++},loadingDone(){this.loading--,this.loading<0&&(this.loading=0)}}}),p=async({url:a,data:t={}},e)=>{const s=d();let p={};if("delete_token"in e&&e.delete_token)p.Authorization&&delete p.Authorization;else{const a=l()?l():"";p.Authorization="Bearer "+a}"delete_appid"in e&&e.delete_appid?t.UNIAPP_APPID&&delete t.UNIAPP_APPID:t.UNIAPP_APPID=e.appid,"delete_apptype"in e&&e.delete_apptype?t.UNIAPP_APPTYPE&&delete t.UNIAPP_APPTYPE:t.UNIAPP_APPTYPE=e.app_type,e.loading&&(s.loadingStart(),1===s.loading&&i({title:e.loading_text}));const r=await n({url:a,method:"POST",data:t,header:p});return e.loading&&(s.loadingDone(),0===s.loading&&o()),r&&""!=r.data?r.data:(uni.$lu.toast("请求发生错误"),!1)};a.config.api_map_url,a.config.base_assets_url;const r=async(t,e={},i={})=>{const n={...a,...i},o=d();if(!(t in o.api_map)){const a=await p({url:n.config.api_map_url},n);if(!a.status)return uni.$lu.toast("获取接口失败"),!1;o.api_map=a.data.list}return t in o.api_map?await p({url:o.api_map[t],data:e},n):(uni.$lu.toast(`接口不存在 [${t}]`),!1)},u=(t,e,i={},n=(()=>{}))=>{if(t){const o={...a,...i};if(t.status!=o.success_code)return uni.$lu.toast(t.message),void n();e()}};export{r as $,u as a};
|
||||
@ -0,0 +1 @@
|
||||
import{c as a,w as s,i as o,o as e,a as t,b as n}from"./index-DqaBDANc.js";import"./index.BjiQWzit.js";const r={__name:"combo",setup:r=>(r,l)=>{const m=o;return e(),a(m,null,{default:s((()=>[t(" Combo "),n(m,{class:"blank_wrapper"})])),_:1})}};export{r as default};
|
||||
@ -0,0 +1 @@
|
||||
import{c as a,w as s,i as e,o as n,a as d,b as t,n as l,d as r}from"./index-DqaBDANc.js";import"./index.BjiQWzit.js";const i={__name:"index",setup:i=>(i,o)=>{const p=r,u=e;return n(),a(u,null,{default:s((()=>[d(" Index "),t(p,{onClick:o[0]||(o[0]=a=>{l({url:"/pages/main/dev/dev"})})},{default:s((()=>[d("开发测试")])),_:1}),t(u,{class:"blank_wrapper"})])),_:1})}};export{i as default};
|
||||
@ -0,0 +1 @@
|
||||
import{c as a,w as s,i as r,o as e,a as t,b as n}from"./index-DqaBDANc.js";import"./index.BjiQWzit.js";const o={__name:"order",setup:o=>(o,d)=>{const l=r;return e(),a(l,null,{default:s((()=>[t(" Order "),n(l,{class:"blank_wrapper"})])),_:1})}};export{o as default};
|
||||
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="/h5/assets/uni.943b8fef.css">
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<script>
|
||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||
CSS.supports('top: constant(a)'))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||
</script><title>海南现代妇女儿童医院</title>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
<script type="module" crossorigin src="/h5/assets/index-DqaBDANc.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/h5/assets/index-BPRTVkjj.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 401 B |
|
After Width: | Height: | Size: 470 B |
|
After Width: | Height: | Size: 511 B |
|
After Width: | Height: | Size: 476 B |
|
After Width: | Height: | Size: 472 B |
|
After Width: | Height: | Size: 545 B |
|
After Width: | Height: | Size: 365 B |
|
After Width: | Height: | Size: 587 B |
|
After Width: | Height: | Size: 565 B |
@ -0,0 +1,20 @@
|
||||
@font-face {
|
||||
font-family: "customicons"; /* Project id 2878519 */
|
||||
src:url('/static/customicons.ttf') format('truetype');
|
||||
}
|
||||
|
||||
.customicons {
|
||||
font-family: "customicons" !important;
|
||||
}
|
||||
|
||||
.youxi:before {
|
||||
content: "\e60e";
|
||||
}
|
||||
|
||||
.wenjian:before {
|
||||
content: "\e60f";
|
||||
}
|
||||
|
||||
.zhuanfa:before {
|
||||
content: "\e610";
|
||||
}
|
||||
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 4.1 KiB |