PaymentMethod.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /**
  2. * 选择支付方式页面
  3. * @邠心vbe on 2022/01/10
  4. */
  5. import React, { Component } from 'react';
  6. import { View, Text, StyleSheet, Pressable, Image } from 'react-native';
  7. import apiWallet from '../../api/apiWallet';
  8. import Button from '../../components/Button';
  9. import Dialog from '../../components/Dialog';
  10. import ChargeItemSelect from '../../icons/ChargeItemSelect';
  11. import { PageList } from '../Router';
  12. import { PaymentDefault, PAYTYPE } from '../wallet/Payment';
  13. import { WalletTitle } from '../wallet/Topup';
  14. export default class PaymentMethod extends Component {
  15. constructor(props) {
  16. super(props);
  17. this.state = {
  18. cIndex: 0,
  19. selectIndex: 0,
  20. paymentOptions: [],
  21. paymentOptionsWallet: [{
  22. title: "Credit Wallet",
  23. desc: '',
  24. value: PAYTYPE.CREDIT_WALLET,
  25. icon: require('../../images/icon/draw-wallet.png')
  26. }, {
  27. title: "Pay Per Use",
  28. desc: '(SGQR)',
  29. value: PAYTYPE.PAY_PER_USE,
  30. icon: require('../../images/wallet/ic_payperuse.png')
  31. }],
  32. paymentOptionsUse: [{
  33. title: "Pay Per Use",
  34. desc: '(SGQR)',
  35. value: PAYTYPE.PAY_PER_USE,
  36. icon: require('../../images/wallet/ic_payperuse.png')
  37. }, {
  38. title: "Credit Wallet",
  39. desc: '',
  40. value: PAYTYPE.CREDIT_WALLET,
  41. icon: require('../../images/icon/draw-wallet.png')
  42. }],
  43. amountList: [{
  44. amount: 10,
  45. power: 0
  46. }, {
  47. amount: 20,
  48. power: 0
  49. }, {
  50. amount: 40,
  51. power: 0
  52. }],
  53. connectorInfo: {}
  54. };
  55. this.rate = 0
  56. this.ENABLE_2C2P = PaymentDefault.is2c2p;
  57. this.FirstPayPerUse = PaymentDefault.DEFAULT.payType == PAYTYPE.PAY_PER_USE;
  58. }
  59. componentDidMount() {
  60. this.setState({
  61. paymentOptions: this.FirstPayPerUse ? this.state.paymentOptionsUse : this.state.paymentOptionsWallet
  62. });
  63. const params = this.props.route.params;
  64. const info = params.info ?? {};
  65. console.log('----params----', params);
  66. if (info.rate && params.type) {
  67. this.rate = info.rate;
  68. this.setState({
  69. connectorInfo: info,
  70. cIndex: (params.type == PAYTYPE.CREDIT_WALLET) ? 0 : 1
  71. });
  72. this.calculatePower();
  73. }
  74. }
  75. calculatePower() {
  76. if (this.rate > 0) {
  77. this.state.amountList.forEach(item => {
  78. item.power = (item.amount / this.rate).toFixed(0)
  79. });
  80. }
  81. }
  82. changePayType(index) {
  83. this.setState({
  84. cIndex: index
  85. })
  86. }
  87. onConfirm() {
  88. const info = this.state.paymentOptions[this.state.cIndex];
  89. global.paymentOption = {
  90. title: info.title,
  91. value: info.value
  92. };
  93. if (info.value == PAYTYPE.CREDIT_WALLET) {
  94. goBack();
  95. } else {
  96. const amount = this.state.amountList[this.state.selectIndex].amount;
  97. global.paymentOption.amount = amount;
  98. const params = {
  99. payAmount: amount,
  100. fomoPayType: "PAYNOW",
  101. paymentOption: info.value,
  102. chargeBoxId: this.state.connectorInfo.chargeBoxId,
  103. connectorId: this.state.connectorInfo.connectorId
  104. }
  105. //console.log('params',params);
  106. if (params.payAmount) {
  107. //PAYNOW支付
  108. Dialog.showProgressDialog();
  109. apiWallet.doPayment(params).then(res => {
  110. Dialog.dismissLoading();
  111. if (res.data.fomoId && res.data.qrCodeInBase64) {
  112. startPage(PageList.payPeruse, { amount: params.payAmount, base64: res.data.qrCodeInBase64 });
  113. } else {
  114. toastShort('Error 0')
  115. }
  116. }).catch(err => {
  117. Dialog.dismissLoading();
  118. toastShort(err);
  119. });
  120. } else {
  121. toastShort('Error 1')
  122. }
  123. }
  124. }
  125. onConfirmV2() {
  126. const info = this.state.paymentOptions[this.state.cIndex];
  127. global.paymentOption = {
  128. title: info.title,
  129. value: info.value
  130. };
  131. if (info.value == PAYTYPE.CREDIT_WALLET) {
  132. goBack();
  133. } else {
  134. const amount = this.state.amountList[this.state.selectIndex].amount;
  135. global.paymentOption.amount = amount;
  136. const params = {
  137. payAmount: amount,
  138. fomoPayType: "PAYNOW",
  139. paymentOption: info.value,
  140. paymentChannel: "SGQR",
  141. chargeBoxId: this.state.connectorInfo.chargeBoxId,
  142. connectorId: this.state.connectorInfo.connectorId
  143. }
  144. //console.log('params',params);
  145. if (params.payAmount) {
  146. //PAYNOW支付
  147. Dialog.showProgressDialog();
  148. apiWallet.doPaymentV2(params).then(res => {
  149. Dialog.dismissLoading();
  150. if (res.data.webPaymentUrl) {
  151. startPage(PageList.paymentWeb, { amount: params.payAmount, url: res.data.webPaymentUrl, type: 'PayPerUse' });
  152. } else {
  153. toastShort('Error 0')
  154. }
  155. }).catch(err => {
  156. Dialog.dismissLoading();
  157. toastShort(err);
  158. });
  159. /*apiWallet.doPayment(params).then(res => {
  160. Dialog.dismissLoading();
  161. if (res.data.fomoId && res.data.qrCodeInBase64) {
  162. startPage(PageList.payPeruse, { amount: params.payAmount, base64: res.data.qrCodeInBase64 });
  163. } else {
  164. toastShort('Error 0')
  165. }
  166. }).catch(err => {
  167. Dialog.dismissLoading();
  168. toastShort(err);
  169. });*/
  170. } else {
  171. toastShort('Error 2')
  172. }
  173. }
  174. }
  175. render() {
  176. return (
  177. <View style={styles.container}>
  178. <View style={styles.headerView}>
  179. <Text></Text>
  180. </View>
  181. <View style={styles.contentView}>
  182. <View style={styles.optionView}>
  183. <WalletTitle>Payment Option</WalletTitle>
  184. <Text style={styles.subTitle}>Pay with: </Text>
  185. { this.state.paymentOptions.map((item, index) => {
  186. return (
  187. <Pressable
  188. key={index}
  189. style={[
  190. styles.paytypeView,
  191. index > 0 && styles.next,
  192. index == this.state.cIndex && styles.selected
  193. ]}
  194. onPress={() => {
  195. this.changePayType(index);
  196. }}>
  197. <Image
  198. style={styles.accountLogo}
  199. source={item.icon}/>
  200. <Text style={styles.paytypeText}>
  201. {item.title} {' '}
  202. {item.desc ? item.desc : '(Balance '+currency+userInfo.credit+')'}
  203. </Text>
  204. <View style={styles.selectIcon}>
  205. <ChargeItemSelect size={18} selected={index == this.state.cIndex} tint={colorPrimary}/>
  206. </View>
  207. </Pressable>
  208. );
  209. })
  210. }
  211. </View>
  212. { (this.state.cIndex == (this.FirstPayPerUse ? 0 : 1)) &&
  213. <View style={[styles.optionView, ui.flex1]}>
  214. <WalletTitle>Pay Per Use</WalletTitle>
  215. <Text style={styles.subTitle}>Choose Amount:</Text>
  216. <View style={styles.amountItems}>
  217. { this.state.amountList.map((item, index) => {
  218. return (
  219. <Pressable
  220. key={index}
  221. style={[
  222. styles.amountItem,
  223. index > 0 && styles.right,
  224. index == this.state.selectIndex && styles.amountSelect]}
  225. onPress={() => {
  226. this.setState({
  227. selectIndex: index
  228. })
  229. }}>
  230. <Text
  231. style={index == this.state.selectIndex ? styles.amountActive : styles.amountText}>
  232. {currency}{item.amount}
  233. </Text>
  234. <Text style={index == this.state.selectIndex ? styles.powerTextActive : styles.powerText}>~{item.power}kWh</Text>
  235. </Pressable>
  236. );
  237. })
  238. }
  239. </View>
  240. <Text style={ui.flex1}></Text>
  241. <Text style={styles.warningText}>Un-utilized amount will be refunded.</Text>
  242. </View>
  243. }
  244. </View>
  245. <Button
  246. text="Confirm"
  247. style={$margin(16)}
  248. onClick={() => this.ENABLE_2C2P ? this.onConfirmV2() : this.onConfirm()}
  249. />
  250. </View>
  251. );
  252. }
  253. }
  254. const styles = StyleSheet.create({
  255. container: {
  256. flex: 1,
  257. backgroundColor: '#F5F5F5'
  258. },
  259. headerView: {
  260. paddingBottom: 76,
  261. //backgroundColor: colorAccent
  262. },
  263. contentView: {
  264. flex: 1,
  265. padding: 16,
  266. marginTop: -80,
  267. marginBottom: -20
  268. },
  269. optionView: {
  270. padding: 16,
  271. borderRadius: 10,
  272. marginBottom: 16,
  273. backgroundColor: 'white'
  274. },
  275. subTitle: {
  276. color: '#333',
  277. fontSize: 14,
  278. marginTop: 16,
  279. marginBottom: 16
  280. },
  281. paytypeView: {
  282. padding: 16,
  283. borderWidth: 1,
  284. borderColor: '#eee',
  285. borderRadius: 10,
  286. alignItems: 'center',
  287. flexDirection: 'row',
  288. backgroundColor: '#F5F5F5'
  289. },
  290. selected: {
  291. borderColor: colorPrimary
  292. },
  293. next: {
  294. marginTop: 16,
  295. },
  296. paytypeText: {
  297. flex: 1,
  298. color: '#333',
  299. fontSize: 14,
  300. },
  301. selectIcon: {
  302. width: 18,
  303. height: 18,
  304. },
  305. amountItems: {
  306. paddingBottom: 16,
  307. alignItems: 'center',
  308. flexDirection: 'row'
  309. },
  310. amountItem: {
  311. flex: 1,
  312. borderWidth: 1,
  313. borderRadius: 4,
  314. borderColor: '#999',
  315. },
  316. right: {
  317. marginLeft: 20
  318. },
  319. amountSelect: {
  320. borderColor: colorPrimary,
  321. backgroundColor: colorPrimary
  322. },
  323. amountText: {
  324. color: '#666',
  325. fontSize: 24,
  326. height: 50,
  327. lineHeight: 60,
  328. textAlign: 'center'
  329. },
  330. amountActive: {
  331. color: '#fff',
  332. fontSize: 24,
  333. height: 50,
  334. lineHeight: 60,
  335. textAlign: 'center'
  336. },
  337. powerText: {
  338. color: '#333',
  339. padding: 6,
  340. fontSize: 12,
  341. textAlign: 'right',
  342. },
  343. powerTextActive: {
  344. color: '#f0f0f0',
  345. padding: 6,
  346. fontSize: 12,
  347. textAlign: 'right',
  348. },
  349. warningText: {
  350. color: '#ED4A4A',
  351. fontSize: 14,
  352. textAlign: 'center',
  353. paddingBottom: 16
  354. },
  355. accountLogo: {
  356. width: 26,
  357. height: 26,
  358. marginRight: 12
  359. },
  360. });