Skip to content

Commit e5d109f

Browse files
committed
frontend: bitrefill move payment request into its own function
1 parent c0191d4 commit e5d109f

File tree

1 file changed

+68
-61
lines changed

1 file changed

+68
-61
lines changed

frontends/web/src/routes/market/bitrefill.tsx

Lines changed: 68 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,72 @@ export const Bitrefill = ({ accounts, code }: TProps) => {
9696
};
9797
}, [onResize]);
9898

99+
const handlePaymentRequest = useCallback(async (event: MessageEvent) => {
100+
if (!account || pendingPayment) {
101+
return;
102+
}
103+
setPendingPayment(true);
104+
105+
const data = typeof event.data === 'string' ? JSON.parse(event.data) : event.data;
106+
107+
// User clicked "Pay" in checkout
108+
const {
109+
invoiceId,
110+
paymentMethod,
111+
paymentAmount,
112+
paymentAddress,
113+
} = data;
114+
115+
const parsedAmount = await parseExternalBtcAmount(paymentAmount.toString());
116+
if (!parsedAmount.success) {
117+
alertUser(t('unknownError', { errorMessage: 'Invalid amount' }));
118+
setPendingPayment(false);
119+
return;
120+
}
121+
// Ensure expected payment method matches account
122+
if (coinMapping[account.coinCode] !== paymentMethod) {
123+
alertUser(t('unknownError', { errorMessage: 'Payment method mismatch' }));
124+
setPendingPayment(false);
125+
}
126+
127+
const txInput: TTxInput = {
128+
address: paymentAddress,
129+
amount: parsedAmount.amount,
130+
// Always use highest fee rate for Bitrefill spend
131+
useHighestFee: true,
132+
sendAll: 'no',
133+
selectedUTXOs: [],
134+
paymentRequest: null
135+
};
136+
137+
let result = await proposeTx(code, txInput);
138+
if (result.success) {
139+
const txNote = t('generic.paymentRequestNote', {
140+
name: 'Bitrefill',
141+
orderId: invoiceId,
142+
});
143+
144+
setVerifyPaymentRequest({
145+
address: paymentAddress,
146+
...result
147+
});
148+
const sendResult = await sendTx(code, txNote);
149+
setVerifyPaymentRequest(false);
150+
if (!sendResult.success && !('aborted' in sendResult)) {
151+
alertUser(t('unknownError', { errorMessage: sendResult.errorMessage }));
152+
}
153+
} else {
154+
if (result.errorCode === 'insufficientFunds') {
155+
alertUser(t('buy.bitrefill.error.' + result.errorCode));
156+
} else if (result.errorCode) {
157+
alertUser(t('send.error.' + result.errorCode));
158+
} else {
159+
alertUser(t('genericError'));
160+
}
161+
}
162+
setPendingPayment(false);
163+
}, [account, code, pendingPayment, t]);
164+
99165
const handleMessage = useCallback(async (event: MessageEvent) => {
100166
if (
101167
!account
@@ -127,73 +193,14 @@ export const Bitrefill = ({ accounts, code }: TProps) => {
127193
break;
128194
}
129195
case 'payment_intent': {
130-
if (pendingPayment) {
131-
return;
132-
}
133-
setPendingPayment(true);
134-
// User clicked "Pay" in checkout
135-
const {
136-
invoiceId,
137-
paymentMethod,
138-
paymentAmount,
139-
paymentAddress,
140-
} = data;
141-
142-
const parsedAmount = await parseExternalBtcAmount(paymentAmount.toString());
143-
if (!parsedAmount.success) {
144-
alertUser(t('unknownError', { errorMessage: 'Invalid amount' }));
145-
setPendingPayment(false);
146-
return;
147-
}
148-
// Ensure expected payment method matches account
149-
if (coinMapping[account.coinCode] !== paymentMethod) {
150-
alertUser(t('unknownError', { errorMessage: 'Payment method mismatch' }));
151-
setPendingPayment(false);
152-
}
153-
154-
const txInput: TTxInput = {
155-
address: paymentAddress,
156-
amount: parsedAmount.amount,
157-
// Always use highest fee rate for Bitrefill spend
158-
useHighestFee: true,
159-
sendAll: 'no',
160-
selectedUTXOs: [],
161-
paymentRequest: null
162-
};
163-
164-
let result = await proposeTx(code, txInput);
165-
if (result.success) {
166-
const txNote = t('generic.paymentRequestNote', {
167-
name: 'Bitrefill',
168-
orderId: invoiceId,
169-
});
170-
171-
setVerifyPaymentRequest({
172-
address: paymentAddress,
173-
...result
174-
});
175-
const sendResult = await sendTx(code, txNote);
176-
setVerifyPaymentRequest(false);
177-
if (!sendResult.success && !('aborted' in sendResult)) {
178-
alertUser(t('unknownError', { errorMessage: sendResult.errorMessage }));
179-
}
180-
} else {
181-
if (result.errorCode === 'insufficientFunds') {
182-
alertUser(t('buy.bitrefill.error.' + result.errorCode));
183-
} else if (result.errorCode) {
184-
alertUser(t('send.error.' + result.errorCode));
185-
} else {
186-
alertUser(t('genericError'));
187-
}
188-
}
189-
setPendingPayment(false);
196+
handlePaymentRequest(event);
190197
break;
191198
}
192199
default: {
193200
break;
194201
}
195202
}
196-
}, [account, bitrefillInfo, code, isDarkMode, pendingPayment, t]);
203+
}, [account, bitrefillInfo, handlePaymentRequest, isDarkMode]);
197204

198205
useEffect(() => {
199206
window.addEventListener('message', handleMessage);

0 commit comments

Comments
 (0)