多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
> 后端使用的是laravel yansongda pay库 > https://pay.yansongda.cn/docs/v3/ > 公众号支付 ~~~ <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="/css/font.css"> <link rel="stylesheet" href="/css/mui.min.css"> <title>vip</title> <style> *{ padding: 0; margin: 0; box-sizing: border-box; font-weight: 100; font-size: 15px; direction: rtl; list-style: none; outline: none; font-family: 'ukjTor'; } body{ width: 100%; max-width: 768px; margin: auto; overflow-y: auto; overflow-x: hidden; } .page{ padding: 0 30px; } .top{ height: 40vh; background: url("/images/mob_bg.png") no-repeat; background-size: 100% 100%; } .top .face{ display: flex; justify-content: center; align-items: center; flex-direction: column; text-align: center; padding-top: 50px; } .top .face img{ width: 90px; height: 90px; border-radius: 100%; border: 3px solid #ededed; margin-bottom: 5px; } .top .face div.app_name{ font-weight: bold; color: #000000; } .top .face div{ margin: 5px 0; } .top .face div.id{ color: #444; } .bottom{ margin-top: -80px; } .vip_list .tag_title{ height: 40px; line-height: 40px; color: #000; text-align: center; } .vip_list ul{ margin-top: 10px; } .vip_list ul li{ margin-bottom: 14px; border: 1px solid var(--neutral-light-1, #D3D9EB); align-items: center; border-radius: 16px; padding: 16px; } .vip_list ul li div{ display: flex; justify-content: space-between; } .vip_list ul li.cur .value{ font-size: 26px; } .vip_list ul li.cur .title{ font-size: 18px; margin-top: 10px; } .vip_list ul li.cur{ color: #000000; background: url("/images/mob_bg.png") no-repeat; background-size: 100% 120%; } .vip_list ul li p{ margin-top: 10px; font-size: 13px; } .vip_list ul li.check .value{ font-size: 26px; } .vip_list ul li.check .title{ font-size: 18px; margin-top: 10px; } .vip_list ul li.check{ margin-top: 22px; position: relative; } .vip_list ul li.check:before{ content: 'تەۋسىيە'; position: absolute; top:-11px; right: 10px; width: 72px; height: 25px; border-radius: 12.5px; border: 1px solid #000; background: #FFF; text-align: center; } .buy_btn{ position: fixed; bottom: 30px; left: 0; width: 100%; } .buy_btn .list{ width: 100%; height: 50px; line-height: 50px; } .buy_btn .list{ display: flex; flex-direction: row-reverse; } .buy_btn .list>div{ width: 50%; text-align: center; } .buy_btn .list>div.text{ background-color: #8B55FF; color: #fff; border-radius: 0 40px 40px 0; } .buy_btn .list>div.dollar{ background-color: #000; color: #fff; border-radius: 40px 0 0 40px; } .permission{ border-radius: 16px; border: 1px solid #DADEE5; background: #FFF; margin: 30px 30px 120px; } .per_title{ line-height: 30px; height: 30px; padding-right: 10px; margin-top: 10px; } .permission ul{ display: flex; justify-content: space-around; color: #8691A7; padding: 16px 0 ; opacity: 0.5; } .permission ul li{ display: flex; flex-direction: column; align-items: center; } .permission ul li span{ font-size: 12px; } .permission ul li img{ width: 30px; } .loading-container { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0.8); z-index: 9999; display: flex; justify-content: center; align-items: center; } .loading-spinner { width: 40px; height: 40px; border-radius: 50%; border: 4px solid #ccc; border-top-color: #333; animation: spin 1s infinite linear; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } #loading{ display: none; } .mui-toast-container{ bottom: 40% !important; } </style> </head> <body> <div class="top"> <div class="face"> <img src="/images/avatar.png" alt=""> <div class="app_name">{{ $user['nickname'] ?? '翻译' }}</div> <div class="id">{{ isset($user['user_id']) ? 'ID: '. $user['user_id'] : '' }}</div> </div> </div> <div class="page bottom"> <div class="vip_list"> <div class="tag_title">{{ $data['vip_data']['end_time_text'] }}</div> <ul class="vip_ul"> @foreach($data['vip_data']['vip_list'] as $item) <li onclick="get_current(this, '{{ $item->price }}', {{ $item->id }})" @if($item->check == 1) class="cur check" @endif> <div> <span class="title">{{ $item->title }}</span> <span class="value">{{ $item->price }}¥</span> </div> @if($item->check == 1) <p>{{ $item->text2 }}</p> @endif </li> @endforeach </ul> </div> </div> <div class="permission"> <div class="per_title">ئەزا ئىمتىيازى</div> <ul> @foreach($data['vip_data']['vip_permission']['list'] as $item) <li> <span><img src="{{ $item->thumb }}" alt=""></span> <span>{{ $item->name }}</span> </li> @endforeach </ul> </div> <div class="buy_btn page"> <div class="list"> <div class="dollar">{{ $default_price }}</div> <div onclick="pay()" class="text"> @if(isset($user['info'])) @if($user['info']['is_vip'] == 0) سېتىۋېلىش @else ئۇزارتىش @endif @else سېتىۋېلىش @endif </div> </div> </div> <div id="loading" class="loading-container"> <div class="loading-spinner"></div> </div> <script src="/js/jquery3.6.4.js"></script> <script src="/js/mui.min.js"></script> <!--微信的JSSDK--> <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> <script> $(function() { <!--通过config接口注入权限验证配置--> wx.config(@json($config)); }); let id = {{ $default_id }}; function get_current(_that, price, item_id){ let vip_ul = document.querySelectorAll('.vip_ul li') let dollar = document.querySelector('.dollar') vip_ul.forEach(item =>{ item.classList.remove('cur') }) _that.classList.add('cur') dollar.innerText = price + ' يۈەن' id = item_id; } function pay(){ showLoading() fetch("/trans/mp_pay", { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id, '_token': '{{ csrf_token() }}' }) }).then(response => response.json()).then(data => { hideLoading() if(data.code == 419){ mui.alert('', data.msg,'ماقۇل، ھازىرلا كىرەي', function (){ location.href = '{{ route('trans.vip', ['type'=>'login']) }}' }) return false; } //弹出支付窗口 wx.chooseWXPay({ timestamp: data.timeStamp, // 支付签名时间戳, nonceStr: data.nonceStr, // 支付签名随机串,不长于 32 位 package: data.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=xxxx) signType: data.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5' paySign: data.paySign, // 支付签名 success: function (res) { // 支付成功后的回调函数 console.log(res) // res.errMsg === 'chooseWXPay:ok'方式判断前端返回,微信团队郑重提示: // res.errMsg将在用户支付成功后返回ok,但并不保证它绝对可靠, 切记。 if (res.errMsg === 'chooseWXPay:ok') { mui.toast('پۇل تۆلەش تامام',{ duration:'long', type:'div' }) setTimeout(()=>{ location.reload() },2000) } }, cancel: function (res) { mui.toast('پۇل تۆلەش مەغلۇب بولدى!',{ duration:'long', type:'div' }) }, // 支付失败回调函数 fail: function (res) { mui.toast('پۇل تۆلەش مەغلۇب بولدى!',{ duration:'long', type:'div' }) } }); }).catch(error => { console.error('error') }) } // 显示加载中效果 function showLoading() { document.getElementById('loading').style.display = 'flex'; } // 隐藏加载中效果 function hideLoading() { document.getElementById('loading').style.display = 'none'; } </script> </body> </html> ~~~