Livewire多步骤表单中Razorpay按钮脚本加载异常求助
Razorpay支付按钮在分步表单回退时不加载的解决办法
问题说明
开发基于$currentStep条件展示的3步表单,仅第1步显示Razorpay支付按钮。页面刷新时脚本正常加载,但从第2步返回第1步时,脚本无法加载,组件刷新也无效,需实现回退到第1步时正常加载支付按钮。
原代码:
@if ($currentStep == 1) <form action="{{ route('payment.store') }}" method="POST"> @csrf <script src="https://checkout.razorpay.com/v1/checkout.js" data-key="{{ env('RAZORPAY_KEY_ID') }}" data-amount="{{$price}}" data-buttontext="Pay {{$price}} INR" data-name="{{ env('APP_NAME') }}" data-description="Razorpay payment" data-image="/images/logo-icon.png" data-prefill.name="TEST" data-prefill.email="test@gmail.com" data-theme.color="#ff7529"> </script> </form> @endif
解决思路及代码
问题根源是Livewire更新DOM时,动态插入的脚本不会自动重新执行。改用手动初始化Razorpay实例的方式,避免依赖脚本的自动渲染逻辑。
方法一:全局加载脚本+手动初始化
- 在项目布局文件(如
app.blade.php)中全局引入Razorpay脚本,确保脚本只加载一次:
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
- 修改组件中的支付按钮代码:
@if ($currentStep == 1) <form id="payment-form" action="{{ route('payment.store') }}" method="POST"> @csrf <button type="button" id="razorpay-pay-btn">Pay {{$price}} INR</button> </form> @push('scripts') <script> // 监听Livewire导航/更新事件,确保切换到第1步时初始化 document.addEventListener('livewire:navigated', () => { const payBtn = document.getElementById('razorpay-pay-btn'); if (!payBtn) return; // 避免重复绑定事件 payBtn.onclick = null; const options = { key: "{{ env('RAZORPAY_KEY_ID') }}", amount: "{{$price}}", name: "{{ env('APP_NAME') }}", description: "Razorpay payment", image: "/images/logo-icon.png", prefill: { name: "TEST", email: "test@gmail.com" }, theme: { color: "#ff7529" }, handler: (response) => { // 将支付ID添加到表单并提交 const paymentIdInput = document.createElement('input'); paymentIdInput.type = 'hidden'; paymentIdInput.name = 'razorpay_payment_id'; paymentIdInput.value = response.razorpay_payment_id; document.getElementById('payment-form').appendChild(paymentIdInput); document.getElementById('payment-form').submit(); } }; const rzpInstance = new Razorpay(options); payBtn.onclick = (e) => { rzpInstance.open(); e.preventDefault(); }; }); </script> @endpush @endif
方法二:动态加载脚本+手动初始化
如果不想全局加载脚本,可在进入第1步时动态加载并初始化:
@if ($currentStep == 1) <form id="payment-form" action="{{ route('payment.store') }}" method="POST"> @csrf <button type="button" id="razorpay-pay-btn">Pay {{$price}} INR</button> </form> @push('scripts') <script> document.addEventListener('livewire:update', () => { const payBtn = document.getElementById('razorpay-pay-btn'); if (!payBtn) return; function initRazorpay() { const options = { key: "{{ env('RAZORPAY_KEY_ID') }}", amount: "{{$price}}", name: "{{ env('APP_NAME') }}", description: "Razorpay payment", image: "/images/logo-icon.png", prefill: { name: "TEST", email: "test@gmail.com" }, theme: { color: "#ff7529" }, handler: (response) => { const paymentIdInput = document.createElement('input'); paymentIdInput.type = 'hidden'; paymentIdInput.name = 'razorpay_payment_id'; paymentIdInput.value = response.razorpay_payment_id; document.getElementById('payment-form').appendChild(paymentIdInput); document.getElementById('payment-form').submit(); } }; const rzpInstance = new Razorpay(options); payBtn.onclick = (e) => { rzpInstance.open(); e.preventDefault(); }; } // 检查脚本是否已加载,未加载则动态插入 if (!window.Razorpay) { const script = document.createElement('script'); script.src = 'https://checkout.razorpay.com/v1/checkout.js'; script.onload = initRazorpay; document.body.appendChild(script); } else { initRazorpay(); } }); </script> @endpush @endif
内容的提问来源于stack exchange,提问作者Dhaval Kacha
相关产品推荐
相关产品推荐

