Skip to content

Commit 1c83fa8

Browse files
authored
Merge pull request #5937 from Bowrna/fix_razorpay_not_defined
fix(billing): Razorpay not defined error if checkout script loading takes time
2 parents 27d4f24 + 9b7a3f3 commit 1c83fa8

File tree

3 files changed

+43
-25
lines changed

3 files changed

+43
-25
lines changed

dashboard/src/components/billing/BuyCreditsRazorpay.vue

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@
2222
class="w-full"
2323
size="md"
2424
variant="solid"
25-
:label="`Proceed to payment using ${paypalEnabled ? 'PayPal' : 'Razorpay'}`"
26-
:loading="createRazorpayOrder.loading"
25+
:label="
26+
razorpayScriptLoading
27+
? 'Loading payment gateway...'
28+
: `Proceed to payment using ${paypalEnabled ? 'PayPal' : 'Razorpay'}`
29+
"
30+
:loading="createRazorpayOrder.loading || razorpayScriptLoading"
2731
@click="createRazorpayOrder.submit()"
2832
/>
2933
<Button
@@ -42,6 +46,7 @@ import { Button, ErrorMessage, FeatherIcon, createResource } from 'frappe-ui';
4246
import { ref, onMounted, onBeforeUnmount, inject } from 'vue';
4347
import { toast } from 'vue-sonner';
4448
import { DashboardError } from '../../utils/error';
49+
import { loadRazorpayScript } from '../../utils/razorpay';
4550
4651
const props = defineProps({
4752
amount: {
@@ -73,20 +78,18 @@ const paypalEnabled = team.doc.currency === 'USD' && props.paypalEnabled;
7378
const isPaymentComplete = ref(false);
7479
const isVerifyingPayment = ref(false);
7580
76-
const razorpayCheckoutJS = ref(null);
81+
const razorpayScriptLoading = ref(!window.Razorpay);
7782
7883
onMounted(() => {
79-
razorpayCheckoutJS.value = document.createElement('script');
80-
razorpayCheckoutJS.value.setAttribute(
81-
'src',
82-
'https://checkout.razorpay.com/v1/checkout.js',
83-
);
84-
razorpayCheckoutJS.value.async = true;
85-
document.head.appendChild(razorpayCheckoutJS.value);
86-
});
87-
88-
onBeforeUnmount(() => {
89-
razorpayCheckoutJS.value?.remove();
84+
loadRazorpayScript()
85+
.then(() => {
86+
razorpayScriptLoading.value = false;
87+
})
88+
.catch(() => {
89+
toast.error(
90+
'Failed to load payment gateway. Please refresh and try again.',
91+
);
92+
});
9093
});
9194
9295
const createRazorpayOrder = createResource({
@@ -96,7 +99,10 @@ const createRazorpayOrder = createResource({
9699
transaction_type: props.type,
97100
doc_name: props.docName,
98101
},
99-
onSuccess: (data) => processOrder(data),
102+
onSuccess: async (data) => {
103+
await loadRazorpayScript();
104+
processOrder(data);
105+
},
100106
validate: () => {
101107
if (props.amount < props.minimumAmount) {
102108
throw new DashboardError('Amount less than minimum amount required');

dashboard/src/components/billing/UPIAutopayForm.vue

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
<script>
4545
import { FormControl, Button, ErrorMessage } from 'frappe-ui';
4646
import { toast } from 'vue-sonner';
47+
import { loadRazorpayScript } from '../../utils/razorpay';
4748
4849
export default {
4950
name: 'UPIAutopayForm',
@@ -64,7 +65,7 @@ export default {
6465
};
6566
},
6667
mounted() {
67-
this.loadRazorpayScript();
68+
loadRazorpayScript();
6869
if (this.isBackground) {
6970
this.$resources.createRazorpayMandate.submit();
7071
}
@@ -108,14 +109,6 @@ export default {
108109
},
109110
},
110111
methods: {
111-
loadRazorpayScript() {
112-
if (window.Razorpay) return;
113-
const script = document.createElement('script');
114-
script.src = 'https://checkout.razorpay.com/v1/checkout.js';
115-
script.async = true;
116-
document.head.appendChild(script);
117-
},
118-
119112
setupAutopay() {
120113
if (!this.maxAmount || this.maxAmount < 500) {
121114
toast.error('Maximum amount must be at least ₹500');
@@ -129,7 +122,8 @@ export default {
129122
// this.$resources.createRazorpayMandate.submit();
130123
},
131124
132-
openRazorpayCheckout(orderData) {
125+
async openRazorpayCheckout(orderData) {
126+
await loadRazorpayScript();
133127
const options = {
134128
key: orderData.key_id,
135129
order_id: orderData.order_id,

dashboard/src/utils/razorpay.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
let razorpayScriptPromise = null;
2+
3+
export function loadRazorpayScript() {
4+
if (window.Razorpay) return Promise.resolve();
5+
if (!razorpayScriptPromise) {
6+
razorpayScriptPromise = new Promise((resolve, reject) => {
7+
const script = document.createElement('script');
8+
script.src = 'https://checkout.razorpay.com/v1/checkout.js';
9+
script.onload = resolve;
10+
script.onerror = () => {
11+
razorpayScriptPromise = null; // allow retry on next call
12+
reject(new Error('Failed to load Razorpay checkout script'));
13+
};
14+
document.head.appendChild(script);
15+
});
16+
}
17+
return razorpayScriptPromise;
18+
}

0 commit comments

Comments
 (0)