Skip to content

Instantly share code, notes, and snippets.

@abdullahIsa
Last active March 25, 2023 06:20
Show Gist options
  • Save abdullahIsa/6848eacaf346645113b52a3aee40e089 to your computer and use it in GitHub Desktop.
Save abdullahIsa/6848eacaf346645113b52a3aee40e089 to your computer and use it in GitHub Desktop.
import React, {useCallback, useEffect, useState} from 'react';
import {Image, StyleSheet, Text, View, TouchableOpacity} from 'react-native';
import {initStripe, useStripe} from '@stripe/stripe-react-native';
import {COMPANY} from '@env';
import {colors} from './colors';
import Button from './button';
import {getPaymentIntent, getPublishableKey} from './stripeHelper';
import {AccountSettingsHelpers} from '../setting';
import {RootNavigation} from '../navigation/RootNavigation';
const PaymentsUICustomScreen = (props, ref) => {
const {
children = null,
paymentDetails,
successfullTransaction = () => null,
getPaymentMethod = () => null,
isCardSetter = false,
autoInit = true,
} = props;
const {
userDetails,
amount,
totalFees,
summary,
secondaryButtonTittle,
trnxType,
purpose,
fromKey,
toKey,
} = paymentDetails;
const {initPaymentSheet, presentPaymentSheet, confirmPaymentSheetPayment} =
useStripe();
const [paymentSheetEnabled, setPaymentSheetEnabled] = useState(false);
const [loading, setLoading] = useState(false);
const [paymentMethod, setPaymentMethod] = useState(null);
const [customerId, setcustomerId] = useState(null);
const [currentPaymentInfo, setCurrentPaymentInfo] = useState(null);
useEffect(() => {
if (autoInit === true) {
initialize();
}
}, []);
React.useImperativeHandle(ref, () => ({
initialize,
choosePaymentOption,
onPressPay,
}));
const goToSupport = useCallback(() => {
RootNavigation('Support');
}, []);
const initialize = async () => {
if (
(amount === 0 || amount === '' || amount === '0' || amount < 10) &&
isCardSetter !== true
) {
AccountSettingsHelpers.errMessage({
message: 'Invalid amount!',
});
return {error: true, message: 'Invalid amount!'};
}
const {publishableKey} = await getPublishableKey(null);
if (publishableKey) {
await initStripe({
publishableKey,
merchantIdentifier: `merchant.com.${COMPANY}`,
urlScheme:
paymentMethod === 'wechat_pay' ? undefined : 'stripe-example',
setUrlSchemeOnAndroid: true,
});
setLoading(false);
return await initialisePaymentSheet();
} else {
return {error: true, message: 'Error failed to process!'};
}
};
const fetchPaymentSheetParams = async () => {
const {paymentIntent, paymentId, ephemeralKey, customer} =
await getPaymentIntent({
price: totalFees,
amount,
email: userDetails.email,
customer: userDetails?.customerServicePayementId,
trnxType,
purpose,
summary,
fromKey,
toKey,
});
const objinfo = {
paymentIntent,
ephemeralKey,
customer,
paymentId,
trnxType,
purpose,
summary,
fromKey,
toKey,
};
setCurrentPaymentInfo(objinfo);
return objinfo;
};
const initialisePaymentSheet = async () => {
console.log('amount', amount);
if (
(amount === 0 || amount === '' || amount === '0' || amount < 10) &&
isCardSetter !== true
) {
AccountSettingsHelpers.errMessage({
message: 'Invalid amount!',
});
return {error: true, message: 'Invalid amount!'};
}
setLoading(true);
try {
const {paymentIntent, ephemeralKey, customer} =
await fetchPaymentSheetParams();
setcustomerId(customer);
console.log('paymentIntent', paymentIntent);
console.log('ephemeralKey', ephemeralKey);
console.log('customer', customer);
const resultPaymentSheet = await initPaymentSheet({
customerId: customer,
customerEphemeralKeySecret: ephemeralKey,
paymentIntentClientSecret: paymentIntent,
customFlow: true,
merchantDisplayName: `${COMPANY}.LTD`,
applePay: true,
merchantCountryCode: 'US',
style: 'alwaysDark',
googlePay: true,
testEnv: __DEV__,
primaryButtonColor: '#635BFF',
returnURL: 'stripe-example://stripe-redirect',
defaultBillingDetails: userDetails,
});
console.log('resultPaymentSheet', resultPaymentSheet);
const {error, paymentOption} = resultPaymentSheet;
console.log('error:', error);
console.log('paymentOption:', paymentOption);
if (!error) {
setPaymentSheetEnabled(true);
} else {
AccountSettingsHelpers.errMessage({
message: `Error code: ${error.code}, ${error.message}`,
});
setLoading(false);
return {
error: true,
message:
'Having issues with payemnt system, please try again or contact support!',
};
}
setPaymentMethod(paymentOption);
getPaymentMethod(paymentOption);
setLoading(false);
return {
error: false
};
} catch (error) {
console.log('initialisePaymentSheet error:', error);
AccountSettingsHelpers.errMessage({
message:
'Having issues with payemnt system, please try again or contact support!',
});
setLoading(false);
return {
error: true,
message:
'Having issues with payemnt system, please try again or contact support!',
};
}
};
const choosePaymentOption = async () => {
// if (paymentMethod === undefined || paymentMethod === null) return;
const {error, paymentOption} = await presentPaymentSheet();
if (error) {
AccountSettingsHelpers.errMessage({
message: `Error code: ${error.code}, ${error.message}`,
});
} else if (paymentOption) {
const objPaymentMethod = {
label: paymentOption.label,
image: paymentOption.image,
};
setPaymentMethod(objPaymentMethod);
getPaymentMethod(objPaymentMethod);
} else {
setPaymentMethod(null);
getPaymentMethod(null);
}
return {error, paymentOption};
};
const onPressPay = async () => {
setLoading(true);
const {error} = await confirmPaymentSheetPayment();
if (error) {
AccountSettingsHelpers.errMessage({
message: `Error code: ${error.code}, ${error.message}`,
});
} else {
setPaymentSheetEnabled(false);
successfullTransaction({
error: false,
successful: true,
customerId,
payed: true,
currentPaymentInfo,
summary,
amount,
});
}
setLoading(false);
return {error};
};
return (
<>
{children !== undefined && children !== null ? (
children
) : (
<>
<View style={{backgroundColor: 'transparent'}}>
<Button
variant="primary"
loading={loading}
title={
paymentMethod !== undefined &&
paymentMethod !== null &&
paymentMethod !== '' ? (
<View style={styles.row}>
<Image
source={{
uri: `data:image/png;base64,${paymentMethod.image}`,
}}
style={styles.image}
/>
<Text style={styles.text}>{paymentMethod.label}</Text>
</View>
) : (
'Choose payment method'
)
}
disabled={!paymentSheetEnabled}
onPress={choosePaymentOption}
/>
</View>
<View style={styles.section}>
<Button
variant="primary"
loading={loading}
disabled={!paymentMethod || !paymentSheetEnabled}
title={secondaryButtonTittle}
onPress={onPressPay}
/>
</View>
</>
)}
<TouchableOpacity onPress={goToSupport}>
<Text
style={{
opacity: 5,
color: 'grey',
alignSelf: 'center',
marginTop: 15,
}}>
Having issues? click to email support
</Text>
</TouchableOpacity>
</>
);
};
const styles = StyleSheet.create({
flex: {
flex: 1,
},
row: {
flexDirection: 'row',
alignItems: 'center',
},
section: {
marginTop: 40,
},
title: {
fontSize: 18,
marginBottom: 20,
fontWeight: 'bold',
},
paymentMethodTitle: {
color: colors.slate,
fontWeight: 'bold',
},
image: {
width: 26,
height: 20,
},
text: {
color: colors.white,
fontSize: 16,
fontWeight: '600',
marginLeft: 12,
},
});
export default React.forwardRef(PaymentsUICustomScreen);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment