|
@@ -0,0 +1,357 @@
|
|
|
|
|
+/**
|
|
|
|
|
+ * 输入信用卡信息页面
|
|
|
|
|
+ * @邠心vbe on 2021/06/09
|
|
|
|
|
+ */
|
|
|
|
|
+import React, { Component } from 'react';
|
|
|
|
|
+import { View, Text, StyleSheet, TextInput, KeyboardAvoidingView } from 'react-native';
|
|
|
|
|
+import Button from '../../components/Button';
|
|
|
|
|
+import apiWallet from '../../api/apiWallet';
|
|
|
|
|
+import Dialog from '../../components/Dialog';
|
|
|
|
|
+import { PageList } from '../Router';
|
|
|
|
|
+
|
|
|
|
|
+export default class FormCard extends Component {
|
|
|
|
|
+ constructor(props) {
|
|
|
|
|
+ super(props);
|
|
|
|
|
+ this.state = {
|
|
|
|
|
+ amount: 0,
|
|
|
|
|
+ payType: '',
|
|
|
|
|
+ payUrl: 'http://www.taobao.com',
|
|
|
|
|
+ validTill: '',
|
|
|
|
|
+ isUrlPage: false
|
|
|
|
|
+ };
|
|
|
|
|
+ this.form = {}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ componentDidMount() {
|
|
|
|
|
+ if (this.props.route.params.amount) {
|
|
|
|
|
+ this.setState({
|
|
|
|
|
+ amount: this.props.route.params.amount,
|
|
|
|
|
+ payType: this.props.route.params.payType
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ validate() {
|
|
|
|
|
+ if (!this.form.nameOnCard) {
|
|
|
|
|
+ toastShort($t('payment.plsInputCardName'));
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!this.form.cardNumber) {
|
|
|
|
|
+ toastShort($t('payment.plsInputCardNo'));
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!/^\d{9,}$/.test(this.form.cardNumber)) {
|
|
|
|
|
+ toastShort($t('payment.errInputCardNo'));
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!this.state.validTill) {
|
|
|
|
|
+ toastShort($t('payment.plsInputTill'));
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!/^(0[1-9]|1[0-2])\/(2[1-9]|[3-5][0-9])/.test(this.state.validTill)) {
|
|
|
|
|
+ toastShort($t('payment.errInputTill'));
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!this.form.cardCvv) {
|
|
|
|
|
+ toastShort($t('payment.plsInputCvv'));
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!/^\d{3}$/.test(this.form.cardCvv)) {
|
|
|
|
|
+ toastShort($t('payment.errInputCvv'));
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ const params = this.form;
|
|
|
|
|
+ params.validTill = this.state.validTill;
|
|
|
|
|
+ this.topup(params);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ topup(params) {
|
|
|
|
|
+ const topup = {
|
|
|
|
|
+ payAmount: this.state.amount,
|
|
|
|
|
+ fomoPayType: this.state.payType,
|
|
|
|
|
+ userCard: params
|
|
|
|
|
+ }
|
|
|
|
|
+ Dialog.showProgressDialog();
|
|
|
|
|
+ apiWallet.doPayment(topup).then(res => {
|
|
|
|
|
+ Dialog.dismissLoading();
|
|
|
|
|
+ if (res.data.fomoId && res.data.url) {
|
|
|
|
|
+ startPage(PageList.paycard, { url: res.data.url })
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(err => {
|
|
|
|
|
+ Dialog.dismissLoading();
|
|
|
|
|
+ toastShort(err);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ render() {
|
|
|
|
|
+ return (
|
|
|
|
|
+ this.state.isUrlPage
|
|
|
|
|
+ ? <View style={styles.container}>
|
|
|
|
|
+ <View style={[ui.flex3, ui.flexvc]}>
|
|
|
|
|
+ <Text style={styles.payAmount}>
|
|
|
|
|
+ <Text style={styles.currency}>{currency+' '}</Text>
|
|
|
|
|
+ {this.state.amount}
|
|
|
|
|
+ </Text>
|
|
|
|
|
+ <Text style={styles.amountTitle}>{$t('wallet.topUp')}</Text>
|
|
|
|
|
+ <View style={styles.buttonGroup}>
|
|
|
|
|
+ <Button
|
|
|
|
|
+ style={styles.button2}
|
|
|
|
|
+ text={$t('payment.openInBrowser')}
|
|
|
|
|
+ elevation={1.5}
|
|
|
|
|
+ onClick={() => {
|
|
|
|
|
+ this.openBrowser();
|
|
|
|
|
+ }}/>
|
|
|
|
|
+ <View style={styles.button}>
|
|
|
|
|
+ <Button
|
|
|
|
|
+ text={$t('payment.paymentCompleted')}
|
|
|
|
|
+ elevation={1.5}
|
|
|
|
|
+ onClick={() => {
|
|
|
|
|
+ goBack();
|
|
|
|
|
+ }}/>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <Text style={ui.flex1}></Text>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ : <KeyboardAvoidingView style={styles.container}>
|
|
|
|
|
+ <View style={styles.formView}>
|
|
|
|
|
+ <Text style={styles.label}>{$t('payment.labelCardName')}</Text>
|
|
|
|
|
+ <TextInput
|
|
|
|
|
+ style={styles.cardNameInput}
|
|
|
|
|
+ placeholder={$t('payment.hintCardName')}
|
|
|
|
|
+ placeholderTextColor={textPlacehoder}
|
|
|
|
|
+ maxLength={50}
|
|
|
|
|
+ onChangeText={text => this.form.nameOnCard = text}/>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View style={styles.formView}>
|
|
|
|
|
+ <Text style={styles.label}>{$t('payment.labelCardNo')}</Text>
|
|
|
|
|
+ <View style={styles.cardNumberRow}>
|
|
|
|
|
+ <FontAwesome
|
|
|
|
|
+ name='credit-card'
|
|
|
|
|
+ size={24}
|
|
|
|
|
+ color={colorPrimary}/>
|
|
|
|
|
+ <Text style={styles.leftLine}/>
|
|
|
|
|
+ <TextInput
|
|
|
|
|
+ style={styles.cardNumber}
|
|
|
|
|
+ placeholder={$t('payment.labelCardNo')}
|
|
|
|
|
+ placeholderTextColor={textPlacehoder}
|
|
|
|
|
+ maxLength={25}
|
|
|
|
|
+ keyboardType={'numeric'}
|
|
|
|
|
+ onChangeText={text => {
|
|
|
|
|
+ this.form.cardNumber = text;
|
|
|
|
|
+ }}/>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View style={styles.formRow}>
|
|
|
|
|
+ <View style={styles.formColumn}>
|
|
|
|
|
+ <Text style={styles.label}>{$t('payment.labelValidTill')}</Text>
|
|
|
|
|
+ <TipInput
|
|
|
|
|
+ placeholder={$t('payment.hintValidTill')}
|
|
|
|
|
+ maxLength={5}
|
|
|
|
|
+ keyboardType={'numeric'}
|
|
|
|
|
+ value={this.state.validTill}
|
|
|
|
|
+ onChangeText={text => {
|
|
|
|
|
+ if (this.state.validTill.length == 2 && text.length == 3) {
|
|
|
|
|
+ if (text.indexOf('/') == -1) {
|
|
|
|
|
+ let s = this.state.validTill + '/' + text.substring(2)
|
|
|
|
|
+ this.setState({
|
|
|
|
|
+ validTill: s
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.setState({
|
|
|
|
|
+ validTill: text
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.setState({
|
|
|
|
|
+ validTill: text
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }}/>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ <View style={styles.formColumn}>
|
|
|
|
|
+ <Text style={styles.label}>CVV</Text>
|
|
|
|
|
+ <TipInput
|
|
|
|
|
+ placeholder='CVV'
|
|
|
|
|
+ maxLength={6}
|
|
|
|
|
+ secureTextEntry={true}
|
|
|
|
|
+ keyboardType={'numeric'}
|
|
|
|
|
+ onChangeText={text => {
|
|
|
|
|
+ this.form.cardCvv = text;
|
|
|
|
|
+ }}/>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ {/* <Text style={styles.tipsText}>Your card may be charged to make sure it’s vailid.That amount will be automatically refunded.</Text>
|
|
|
|
|
+ <Text style={styles.tipsText}>By adding a card,you have read and agree to our terms and conditions.</Text> */}
|
|
|
|
|
+ <Text style={ui.flex1}></Text>
|
|
|
|
|
+ <View style={styles.buttonView}>
|
|
|
|
|
+ <Button
|
|
|
|
|
+ text={$t('common.confirm')}
|
|
|
|
|
+ elevation={1.5}
|
|
|
|
|
+ onClick={() => {
|
|
|
|
|
+ this.validate();
|
|
|
|
|
+ }}/>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ </KeyboardAvoidingView>
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const TipInput = ({onChangeText, maxLength, placeholder, keyboardType, secureTextEntry = false, value}) => {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <View style={styles.cardInputView}>
|
|
|
|
|
+ <TextInput
|
|
|
|
|
+ style={styles.cardInput}
|
|
|
|
|
+ placeholder={placeholder}
|
|
|
|
|
+ placeholderTextColor={textPlacehoder}
|
|
|
|
|
+ maxLength={maxLength}
|
|
|
|
|
+ secureTextEntry={secureTextEntry}
|
|
|
|
|
+ keyboardType={keyboardType}
|
|
|
|
|
+ onChangeText={onChangeText}
|
|
|
|
|
+ value={value}/>
|
|
|
|
|
+ <MaterialIcons
|
|
|
|
|
+ name='info-outline'
|
|
|
|
|
+ color='#999'
|
|
|
|
|
+ size={16}/>
|
|
|
|
|
+ </View>
|
|
|
|
|
+ );
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const styles = StyleSheet.create({
|
|
|
|
|
+ container: {
|
|
|
|
|
+ width: $vw(100),
|
|
|
|
|
+ flex: 1,
|
|
|
|
|
+ backgroundColor: pageBackground
|
|
|
|
|
+ },
|
|
|
|
|
+ formView: {
|
|
|
|
|
+ paddingTop: 16,
|
|
|
|
|
+ paddingLeft: 16,
|
|
|
|
|
+ paddingRight: 16,
|
|
|
|
|
+ paddingBottom: 4
|
|
|
|
|
+ },
|
|
|
|
|
+ formRow: {
|
|
|
|
|
+ paddingTop: 12,
|
|
|
|
|
+ paddingLeft: 8,
|
|
|
|
|
+ paddingRight: 8,
|
|
|
|
|
+ paddingBottom: 8,
|
|
|
|
|
+ alignItems: 'center',
|
|
|
|
|
+ flexDirection: 'row'
|
|
|
|
|
+ },
|
|
|
|
|
+ formColumn: {
|
|
|
|
|
+ flex: 1,
|
|
|
|
|
+ paddingLeft: 8,
|
|
|
|
|
+ paddingRight: 8
|
|
|
|
|
+ },
|
|
|
|
|
+ label: {
|
|
|
|
|
+ color: textPrimary,
|
|
|
|
|
+ fontSize: 14
|
|
|
|
|
+ },
|
|
|
|
|
+ leftLine: {
|
|
|
|
|
+ width: 1,
|
|
|
|
|
+ height: 20,
|
|
|
|
|
+ marginLeft: 16,
|
|
|
|
|
+ backgroundColor: colorAccent
|
|
|
|
|
+ },
|
|
|
|
|
+ cardNumberRow: {
|
|
|
|
|
+ paddingTop: 8,
|
|
|
|
|
+ alignItems: 'center',
|
|
|
|
|
+ flexDirection: 'row',
|
|
|
|
|
+ },
|
|
|
|
|
+ cardNumber: {
|
|
|
|
|
+ flex: 1,
|
|
|
|
|
+ color: textPrimary,
|
|
|
|
|
+ fontSize: 16,
|
|
|
|
|
+ paddingLeft: 8,
|
|
|
|
|
+ },
|
|
|
|
|
+ cardNameInput: {
|
|
|
|
|
+ color: textPrimary,
|
|
|
|
|
+ fontSize: 14,
|
|
|
|
|
+ lineHeight: 16,
|
|
|
|
|
+ paddingTop: 4,
|
|
|
|
|
+ paddingLeft: 0,
|
|
|
|
|
+ paddingBottom: 4,
|
|
|
|
|
+ borderBottomColor: '#EEE',
|
|
|
|
|
+ borderBottomWidth: 1
|
|
|
|
|
+ },
|
|
|
|
|
+ cardInputView: {
|
|
|
|
|
+ paddingTop: 12,
|
|
|
|
|
+ paddingLeft: 2,
|
|
|
|
|
+ paddingRight: 2,
|
|
|
|
|
+ paddingBottom: 0,
|
|
|
|
|
+ alignItems: 'center',
|
|
|
|
|
+ flexDirection: 'row',
|
|
|
|
|
+ borderBottomColor: '#EEE',
|
|
|
|
|
+ borderBottomWidth: 1
|
|
|
|
|
+ },
|
|
|
|
|
+ cardInput: {
|
|
|
|
|
+ flex: 1,
|
|
|
|
|
+ ...$padding(4, 0),
|
|
|
|
|
+ color: textPrimary,
|
|
|
|
|
+ fontSize: 14,
|
|
|
|
|
+ },
|
|
|
|
|
+ countryRow: {
|
|
|
|
|
+ paddingTop: 8,
|
|
|
|
|
+ paddingBottom: 4,
|
|
|
|
|
+ alignItems: 'flex-end',
|
|
|
|
|
+ flexDirection: 'row',
|
|
|
|
|
+ borderBottomWidth: 1,
|
|
|
|
|
+ borderBottomColor: '#EEE'
|
|
|
|
|
+ },
|
|
|
|
|
+ countryPicker: {
|
|
|
|
|
+ flex: 1,
|
|
|
|
|
+ color: textPrimary,
|
|
|
|
|
+ fontSize: 14,
|
|
|
|
|
+ paddingTop: 4,
|
|
|
|
|
+ paddingLeft: 16
|
|
|
|
|
+ },
|
|
|
|
|
+ changeText: {
|
|
|
|
|
+ right: 0,
|
|
|
|
|
+ bottom: 0,
|
|
|
|
|
+ padding: 10,
|
|
|
|
|
+ color: '#12A5F9',
|
|
|
|
|
+ fontSize: 12,
|
|
|
|
|
+ position: 'absolute',
|
|
|
|
|
+ backgroundColor: colorLight
|
|
|
|
|
+ },
|
|
|
|
|
+ switchRow: {
|
|
|
|
|
+ padding: 16,
|
|
|
|
|
+ alignItems: 'center',
|
|
|
|
|
+ flexDirection: 'row',
|
|
|
|
|
+ },
|
|
|
|
|
+ tipsText: {
|
|
|
|
|
+ color: textPrimary,
|
|
|
|
|
+ fontSize: 12,
|
|
|
|
|
+ padding: 16,
|
|
|
|
|
+ },
|
|
|
|
|
+ buttonView: {
|
|
|
|
|
+ padding: 16,
|
|
|
|
|
+ marginBottom: 16
|
|
|
|
|
+ },
|
|
|
|
|
+ payAmount: {
|
|
|
|
|
+ color: colorAccent,
|
|
|
|
|
+ fontSize: 50,
|
|
|
|
|
+ paddingRight: 10
|
|
|
|
|
+ },
|
|
|
|
|
+ currency: {
|
|
|
|
|
+ fontSize: 25
|
|
|
|
|
+ },
|
|
|
|
|
+ amountTitle: {
|
|
|
|
|
+ color: '#555',
|
|
|
|
|
+ fontSize: 12
|
|
|
|
|
+ },
|
|
|
|
|
+ buttonGroup: {
|
|
|
|
|
+ width: $vw(70),
|
|
|
|
|
+ paddingTop: 60
|
|
|
|
|
+ },
|
|
|
|
|
+ button: {
|
|
|
|
|
+ margin: 16,
|
|
|
|
|
+ paddingBottom: 16
|
|
|
|
|
+ },
|
|
|
|
|
+ button2: {
|
|
|
|
|
+ marginLeft: 16,
|
|
|
|
|
+ marginRight: 16,
|
|
|
|
|
+ borderColor: '#DDD',
|
|
|
|
|
+ borderWidth: 1,
|
|
|
|
|
+ backgroundColor: colorLight
|
|
|
|
|
+ }
|
|
|
|
|
+})
|