FormCard.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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. maxLength={50}
  118. onChangeText={text => this.form.nameOnCard = text}/>
  119. </View>
  120. <View style={styles.formView}>
  121. <Text style={styles.label}>Card Number</Text>
  122. <View style={styles.cardNumberRow}>
  123. <FontAwesome
  124. name='credit-card'
  125. size={24}
  126. color={colorPrimary}/>
  127. <Text style={styles.leftLine}/>
  128. <TextInput
  129. style={styles.cardNumber}
  130. placeholder='Card Number'
  131. maxLength={25}
  132. keyboardType={'numeric'}
  133. onChangeText={text => {
  134. this.form.cardNumber = text;
  135. }}/>
  136. </View>
  137. </View>
  138. <View style={styles.formRow}>
  139. <View style={styles.formColumn}>
  140. <Text style={styles.label}>Valid Till</Text>
  141. <TipInput
  142. placeholder='MM/YY'
  143. maxLength={5}
  144. keyboardType={'numeric'}
  145. value={this.state.validTill}
  146. onChangeText={text => {
  147. if (this.state.validTill.length == 2 && text.length == 3) {
  148. if (text.indexOf('/') == -1) {
  149. let s = this.state.validTill + '/' + text.substring(2)
  150. this.setState({
  151. validTill: s
  152. });
  153. } else {
  154. this.setState({
  155. validTill: text
  156. });
  157. }
  158. } else {
  159. this.setState({
  160. validTill: text
  161. });
  162. }
  163. }}/>
  164. </View>
  165. <View style={styles.formColumn}>
  166. <Text style={styles.label}>CVV</Text>
  167. <TipInput
  168. placeholder='CVV'
  169. maxLength={6}
  170. secureTextEntry={true}
  171. keyboardType={'numeric'}
  172. onChangeText={text => {
  173. this.form.cardCvv = text;
  174. }}/>
  175. </View>
  176. </View>
  177. {/* <Text style={styles.tipsText}>Your card may be charged to make sure it’s vailid.That amount will be automatically refunded.</Text>
  178. <Text style={styles.tipsText}>By adding a card,you have read and agree to our terms and conditions.</Text> */}
  179. <Text style={ui.flex1}></Text>
  180. <View style={styles.buttonView}>
  181. <Button
  182. text='Confirm'
  183. elevation={1.5}
  184. onClick={() => {
  185. this.validate();
  186. }}/>
  187. </View>
  188. </KeyboardAvoidingView>
  189. );
  190. }
  191. }
  192. const TipInput = ({onChangeText, maxLength, placeholder, keyboardType, secureTextEntry = false, value}) => {
  193. return (
  194. <View style={styles.cardInputView}>
  195. <TextInput
  196. style={styles.cardInput}
  197. placeholder={placeholder}
  198. maxLength={maxLength}
  199. secureTextEntry={secureTextEntry}
  200. keyboardType={keyboardType}
  201. onChangeText={onChangeText}
  202. value={value}/>
  203. <MaterialIcons
  204. name='info-outline'
  205. color='#999'
  206. size={16}/>
  207. </View>
  208. );
  209. }
  210. const styles = StyleSheet.create({
  211. container: {
  212. width: $vw(100),
  213. flex: 1,
  214. backgroundColor: 'white'
  215. },
  216. formView: {
  217. paddingTop: 16,
  218. paddingLeft: 16,
  219. paddingRight: 16,
  220. paddingBottom: 4
  221. },
  222. formRow: {
  223. paddingTop: 12,
  224. paddingLeft: 8,
  225. paddingRight: 8,
  226. paddingBottom: 8,
  227. alignItems: 'center',
  228. flexDirection: 'row'
  229. },
  230. formColumn: {
  231. flex: 1,
  232. paddingLeft: 8,
  233. paddingRight: 8
  234. },
  235. label: {
  236. color: '#333',
  237. fontSize: 14
  238. },
  239. leftLine: {
  240. width: 1,
  241. height: 20,
  242. marginLeft: 16,
  243. backgroundColor: colorAccent
  244. },
  245. cardNumberRow: {
  246. paddingTop: 8,
  247. alignItems: 'center',
  248. flexDirection: 'row',
  249. },
  250. cardNumber: {
  251. flex: 1,
  252. color: '#333',
  253. fontSize: 16,
  254. paddingLeft: 8,
  255. },
  256. cardNameInput: {
  257. color: '#333',
  258. fontSize: 14,
  259. paddingBottom: 2,
  260. borderBottomColor: '#EEE',
  261. borderBottomWidth: 1
  262. },
  263. cardInputView: {
  264. paddingTop: 16,
  265. paddingLeft: 2,
  266. paddingRight: 2,
  267. paddingBottom: 2,
  268. alignItems: 'center',
  269. flexDirection: 'row',
  270. borderBottomColor: '#EEE',
  271. borderBottomWidth: 1
  272. },
  273. cardInput: {
  274. flex: 1,
  275. padding: 0,
  276. color: '#333',
  277. fontSize: 14,
  278. },
  279. countryRow: {
  280. paddingTop: 8,
  281. paddingBottom: 4,
  282. alignItems: 'flex-end',
  283. flexDirection: 'row',
  284. borderBottomWidth: 1,
  285. borderBottomColor: '#EEE'
  286. },
  287. countryPicker: {
  288. flex: 1,
  289. color: '#333',
  290. fontSize: 14,
  291. paddingTop: 4,
  292. paddingLeft: 16
  293. },
  294. changeText: {
  295. right: 0,
  296. bottom: 0,
  297. padding: 10,
  298. color: '#12A5F9',
  299. fontSize: 12,
  300. position: 'absolute',
  301. backgroundColor: 'white',
  302. },
  303. switchRow: {
  304. padding: 16,
  305. alignItems: 'center',
  306. flexDirection: 'row',
  307. },
  308. tipsText: {
  309. color: '#333',
  310. fontSize: 12,
  311. padding: 16,
  312. },
  313. buttonView: {
  314. padding: 16,
  315. marginBottom: 16
  316. },
  317. payAmount: {
  318. color: colorAccent,
  319. fontSize: 50,
  320. paddingRight: 10
  321. },
  322. currency: {
  323. fontSize: 25
  324. },
  325. amountTitle: {
  326. color: '#555',
  327. fontSize: 12
  328. },
  329. buttonGroup: {
  330. width: $vw(70),
  331. paddingTop: 60
  332. },
  333. button: {
  334. margin: 16,
  335. paddingBottom: 16
  336. },
  337. button2: {
  338. marginLeft: 16,
  339. marginRight: 16,
  340. borderColor: '#DDD',
  341. borderWidth: 1,
  342. backgroundColor: '#fff'
  343. }
  344. })