FormCard.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /**
  2. * 输入信用卡信息页面
  3. * @邠心vbe on 2021/06/09
  4. */
  5. import React, { Component } from 'react';
  6. import { View, Text, StyleSheet, TextInput, Linking, ScrollView, KeyboardAvoidingView } from 'react-native';
  7. import Button from '../../components/Button';
  8. import apiWallet from '../../api/apiWallet';
  9. import Dialog from '../../components/Dialog';
  10. import { PageList } from '../Router';
  11. export default class FormCard extends Component {
  12. constructor(props) {
  13. super(props);
  14. this.state = {
  15. amount: 0,
  16. payType: '',
  17. payUrl: 'http://www.taobao.com',
  18. validTill: '',
  19. isUrlPage: false
  20. };
  21. this.form = {}
  22. }
  23. componentDidMount() {
  24. if (this.props.route.params.amount) {
  25. this.setState({
  26. amount: this.props.route.params.amount,
  27. payType: this.props.route.params.payType
  28. });
  29. }
  30. }
  31. validate() {
  32. if (!this.form.nameOnCard) {
  33. toastShort('Please type name on card');
  34. return;
  35. }
  36. if (!this.form.cardNumber) {
  37. toastShort('Please type card number');
  38. return;
  39. }
  40. if (!/^\d{9,}$/.test(this.form.cardNumber)) {
  41. toastShort('Please type a correct card number');
  42. return;
  43. }
  44. if (!this.state.validTill) {
  45. toastShort('Please type valid till');
  46. return;
  47. }
  48. if (!/^(0[1-9]|1[0-2])\/(2[1-9]|[3-5][0-9])/.test(this.state.validTill)) {
  49. toastShort('Please type a correct valid till');
  50. return;
  51. }
  52. if (!this.form.cardCvv) {
  53. toastShort('Please type CVV');
  54. return;
  55. }
  56. if (!/^\d{3}$/.test(this.form.cardCvv)) {
  57. toastShort('Please type a correct CVV');
  58. return;
  59. }
  60. const params = this.form;
  61. params.validTill = this.state.validTill;
  62. this.topup(params);
  63. }
  64. topup(params) {
  65. const topup = {
  66. payAmount: this.state.amount,
  67. fomoPayType: this.state.payType,
  68. userCard: params
  69. }
  70. Dialog.showProgressDialog();
  71. apiWallet.doPayment(topup).then(res => {
  72. Dialog.dismissLoading();
  73. if (res.data.fomoId && res.data.url) {
  74. startPage(PageList.paycard, { url: res.data.url })
  75. }
  76. }).catch(err => {
  77. Dialog.dismissLoading();
  78. toastShort(err);
  79. });
  80. }
  81. render() {
  82. return (
  83. this.state.isUrlPage
  84. ? <View style={styles.container}>
  85. <View style={[ui.flex3, ui.flexvc]}>
  86. <Text style={styles.payAmount}>
  87. <Text style={styles.currency}>{currency+' '}</Text>
  88. {this.state.amount}
  89. </Text>
  90. <Text style={styles.amountTitle}>Top up</Text>
  91. <View style={styles.buttonGroup}>
  92. <Button
  93. style={styles.button2}
  94. text='Open in Browser'
  95. elevation={1.5}
  96. onClick={() => {
  97. this.openBrowser();
  98. }}/>
  99. <View style={styles.button}>
  100. <Button
  101. text='Payment Completed'
  102. elevation={1.5}
  103. onClick={() => {
  104. goBack();
  105. }}/>
  106. </View>
  107. </View>
  108. </View>
  109. <Text style={ui.flex1}></Text>
  110. </View>
  111. : <KeyboardAvoidingView style={styles.container}>
  112. <View style={styles.formView}>
  113. <Text style={styles.label}>Name on Card</Text>
  114. <TextInput
  115. style={styles.cardNameInput}
  116. placeholder={'Your name on card'}
  117. placeholderTextColor={textPlacehoder}
  118. maxLength={50}
  119. onChangeText={text => this.form.nameOnCard = text}/>
  120. </View>
  121. <View style={styles.formView}>
  122. <Text style={styles.label}>Card Number</Text>
  123. <View style={styles.cardNumberRow}>
  124. <FontAwesome
  125. name='credit-card'
  126. size={24}
  127. color={colorPrimary}/>
  128. <Text style={styles.leftLine}/>
  129. <TextInput
  130. style={styles.cardNumber}
  131. placeholder='Card Number'
  132. placeholderTextColor={textPlacehoder}
  133. maxLength={25}
  134. keyboardType={'numeric'}
  135. onChangeText={text => {
  136. this.form.cardNumber = text;
  137. }}/>
  138. </View>
  139. </View>
  140. <View style={styles.formRow}>
  141. <View style={styles.formColumn}>
  142. <Text style={styles.label}>Valid Till</Text>
  143. <TipInput
  144. placeholder='MM/YY'
  145. maxLength={5}
  146. keyboardType={'numeric'}
  147. value={this.state.validTill}
  148. onChangeText={text => {
  149. if (this.state.validTill.length == 2 && text.length == 3) {
  150. if (text.indexOf('/') == -1) {
  151. let s = this.state.validTill + '/' + text.substring(2)
  152. this.setState({
  153. validTill: s
  154. });
  155. } else {
  156. this.setState({
  157. validTill: text
  158. });
  159. }
  160. } else {
  161. this.setState({
  162. validTill: text
  163. });
  164. }
  165. }}/>
  166. </View>
  167. <View style={styles.formColumn}>
  168. <Text style={styles.label}>CVV</Text>
  169. <TipInput
  170. placeholder='CVV'
  171. maxLength={6}
  172. secureTextEntry={true}
  173. keyboardType={'numeric'}
  174. onChangeText={text => {
  175. this.form.cardCvv = text;
  176. }}/>
  177. </View>
  178. </View>
  179. {/* <Text style={styles.tipsText}>Your card may be charged to make sure it’s vailid.That amount will be automatically refunded.</Text>
  180. <Text style={styles.tipsText}>By adding a card,you have read and agree to our terms and conditions.</Text> */}
  181. <Text style={ui.flex1}></Text>
  182. <View style={styles.buttonView}>
  183. <Button
  184. text='Confirm'
  185. elevation={1.5}
  186. onClick={() => {
  187. this.validate();
  188. }}/>
  189. </View>
  190. </KeyboardAvoidingView>
  191. );
  192. }
  193. }
  194. const TipInput = ({onChangeText, maxLength, placeholder, keyboardType, secureTextEntry = false, value}) => {
  195. return (
  196. <View style={styles.cardInputView}>
  197. <TextInput
  198. style={styles.cardInput}
  199. placeholder={placeholder}
  200. placeholderTextColor={textPlacehoder}
  201. maxLength={maxLength}
  202. secureTextEntry={secureTextEntry}
  203. keyboardType={keyboardType}
  204. onChangeText={onChangeText}
  205. value={value}/>
  206. <MaterialIcons
  207. name='info-outline'
  208. color='#999'
  209. size={16}/>
  210. </View>
  211. );
  212. }
  213. const styles = StyleSheet.create({
  214. container: {
  215. width: $vw(100),
  216. flex: 1,
  217. backgroundColor: 'white'
  218. },
  219. formView: {
  220. paddingTop: 16,
  221. paddingLeft: 16,
  222. paddingRight: 16,
  223. paddingBottom: 4
  224. },
  225. formRow: {
  226. paddingTop: 12,
  227. paddingLeft: 8,
  228. paddingRight: 8,
  229. paddingBottom: 8,
  230. alignItems: 'center',
  231. flexDirection: 'row'
  232. },
  233. formColumn: {
  234. flex: 1,
  235. paddingLeft: 8,
  236. paddingRight: 8
  237. },
  238. label: {
  239. color: '#333',
  240. fontSize: 14
  241. },
  242. leftLine: {
  243. width: 1,
  244. height: 20,
  245. marginLeft: 16,
  246. backgroundColor: colorAccent
  247. },
  248. cardNumberRow: {
  249. paddingTop: 8,
  250. alignItems: 'center',
  251. flexDirection: 'row',
  252. },
  253. cardNumber: {
  254. flex: 1,
  255. color: '#333',
  256. fontSize: 16,
  257. paddingLeft: 8,
  258. },
  259. cardNameInput: {
  260. color: '#333',
  261. fontSize: 14,
  262. lineHeight: 16,
  263. paddingTop: 4,
  264. paddingLeft: 0,
  265. paddingBottom: 4,
  266. borderBottomColor: '#EEE',
  267. borderBottomWidth: 1
  268. },
  269. cardInputView: {
  270. paddingTop: 12,
  271. paddingLeft: 2,
  272. paddingRight: 2,
  273. paddingBottom: 0,
  274. alignItems: 'center',
  275. flexDirection: 'row',
  276. borderBottomColor: '#EEE',
  277. borderBottomWidth: 1
  278. },
  279. cardInput: {
  280. flex: 1,
  281. ...$padding(4, 0),
  282. color: '#333',
  283. fontSize: 14,
  284. },
  285. countryRow: {
  286. paddingTop: 8,
  287. paddingBottom: 4,
  288. alignItems: 'flex-end',
  289. flexDirection: 'row',
  290. borderBottomWidth: 1,
  291. borderBottomColor: '#EEE'
  292. },
  293. countryPicker: {
  294. flex: 1,
  295. color: '#333',
  296. fontSize: 14,
  297. paddingTop: 4,
  298. paddingLeft: 16
  299. },
  300. changeText: {
  301. right: 0,
  302. bottom: 0,
  303. padding: 10,
  304. color: '#12A5F9',
  305. fontSize: 12,
  306. position: 'absolute',
  307. backgroundColor: 'white',
  308. },
  309. switchRow: {
  310. padding: 16,
  311. alignItems: 'center',
  312. flexDirection: 'row',
  313. },
  314. tipsText: {
  315. color: '#333',
  316. fontSize: 12,
  317. padding: 16,
  318. },
  319. buttonView: {
  320. padding: 16,
  321. marginBottom: 16
  322. },
  323. payAmount: {
  324. color: colorAccent,
  325. fontSize: 50,
  326. paddingRight: 10
  327. },
  328. currency: {
  329. fontSize: 25
  330. },
  331. amountTitle: {
  332. color: '#555',
  333. fontSize: 12
  334. },
  335. buttonGroup: {
  336. width: $vw(70),
  337. paddingTop: 60
  338. },
  339. button: {
  340. margin: 16,
  341. paddingBottom: 16
  342. },
  343. button2: {
  344. marginLeft: 16,
  345. marginRight: 16,
  346. borderColor: '#DDD',
  347. borderWidth: 1,
  348. backgroundColor: '#fff'
  349. }
  350. })