diff --git a/assets/images/Swile_black.png b/assets/images/Swile_black.png new file mode 100644 index 000000000..18c58b15a Binary files /dev/null and b/assets/images/Swile_black.png differ diff --git a/assets/images/restoflash.png b/assets/images/restoflash.png new file mode 100644 index 000000000..2cda0915c Binary files /dev/null and b/assets/images/restoflash.png differ diff --git a/src/App.js b/src/App.js index cf6a4c522..716ca4836 100644 --- a/src/App.js +++ b/src/App.js @@ -138,6 +138,12 @@ const config = { }, }, }, + CheckoutNav: { + screens: { + CheckoutPaygreenReturn: 'paygreen/return', + CheckoutPaygreenCancel: 'paygreen/cancel', + }, + }, }, }; diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 5765a4daa..be4586149 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -425,7 +425,10 @@ "card": "Credit card", "cash_on_delivery": "Cash on delivery", "edenred": "Edenred", - "edenred+card": "Edenred" + "edenred+card": "Edenred", + "conecs": "Titres-restaurant", + "swile": "Swile", + "restoflash": "Restoflash" }, "CASH_ON_DELIVERY_DISCLAIMER": "You are going to pay by cash on delivery. Please prepare the exact amount and make sure to be reachable.", "STORES": "Stores", @@ -571,6 +574,7 @@ "TASK_DONE": "Done", "TASK_CANCELLED": "Cancelled", "ASK_TO_START_PICKUP_TITLE": "Pickup task", - "ASK_TO_START_PICKUP_MESSAGE": "The pickup task is not yet started." - } + "ASK_TO_START_PICKUP_MESSAGE": "The pickup task is not yet started.", + "PAYGREEN_RETURN_TEXT": "Please wait while we process your payment…" + } } diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index 3efff7961..fb6d8c4d8 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json @@ -525,7 +525,7 @@ "ORDER__SHIPPING_TIME_RANGE__NOT_AVAILABLE": "Indisponible pour l'instant", "EDENRED_ELIGIBLE_AMOUNT": "Montant éligible Ticket Restaurant®", "EDENRED_COMPLEMENT": "Complément", - "BARCODE_TASK_ALREADY_ASSIGNED_TITLE": "Tâche déjà assignée", + "BARCODE_TASK_ALREADY_ASSIGNED_TITLE": "Tâche déjà assignée", "BARCODE_TASK_ALREADY_ASSIGNED_ANOTHER_MESSAGE": "Cette tâche a déjà été assignée à un autre utilisateur", "BARCODE_TASK_ALREADY_ASSIGNED_SELF_MESSAGE": "Cette tâche vous a déjà été assignée", "BARCODE_TASK_ALREADY_ASSIGNED_UNASSIGN": "Désassigner", @@ -543,6 +543,7 @@ "TASK_DONE": "Fait", "TASK_CANCELLED": "Annulée", "ASK_TO_START_PICKUP_TITLE": "Tâche de ramassage", - "ASK_TO_START_PICKUP_MESSAGE": "La tâche de ramassage n'est pas encore commencée." + "ASK_TO_START_PICKUP_MESSAGE": "La tâche de ramassage n'est pas encore commencée.", + "PAYGREEN_RETURN_TEXT": "Veuillez patienter pendant que nous traitons votre paiement…" } } diff --git a/src/navigation/checkout/PaygreenCancel.js b/src/navigation/checkout/PaygreenCancel.js new file mode 100644 index 000000000..f0655c6ab --- /dev/null +++ b/src/navigation/checkout/PaygreenCancel.js @@ -0,0 +1,13 @@ +import React, { useEffect } from 'react'; +import { useNavigation } from '@react-navigation/native'; + +export default () => { + + const navigation = useNavigation(); + + useEffect(() => { + navigation.navigate('CheckoutPayment'); + }, [ navigation ]); + + return null +} diff --git a/src/navigation/checkout/PaygreenReturn.js b/src/navigation/checkout/PaygreenReturn.js new file mode 100644 index 000000000..31be55f96 --- /dev/null +++ b/src/navigation/checkout/PaygreenReturn.js @@ -0,0 +1,27 @@ +import React, { useEffect } from 'react'; +import { View } from 'react-native'; +import { Text } from 'native-base'; +import { useNavigation, useRoute } from '@react-navigation/native'; +import { useDispatch } from 'react-redux'; +import { useTranslation } from 'react-i18next'; + +import { checkout } from '../../redux/Checkout/actions'; + +export default () => { + + const route = useRoute(); + const dispatch = useDispatch(); + const { t } = useTranslation(); + + const paymentOrderId = route.params?.po_id; + + useEffect(() => { + dispatch(checkout('', null, false, route.params.po_id)); + }, [ dispatch, route.params.po_id ]); + + return ( + + { t('PAYGREEN_RETURN_TEXT') } + + ) +} diff --git a/src/navigation/checkout/Payment.js b/src/navigation/checkout/Payment.js index 66d654b54..3a88185cf 100644 --- a/src/navigation/checkout/Payment.js +++ b/src/navigation/checkout/Payment.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import { Center } from 'native-base'; -import { View } from 'react-native'; +import { Linking, View } from 'react-native'; import { connect } from 'react-redux'; import { @@ -41,8 +41,12 @@ class CreditCard extends Component { 'edenred+card': 'CheckoutPaymentMethodEdenred', }; - this.props.setPaymentMethod(type, () => { - this.props.navigation.navigate(routesByMethod[type]); + this.props.setPaymentMethod(type, (result) => { + if (result.redirectUrl) { + Linking.openURL(result.redirectUrl); + } else { + this.props.navigation.navigate(routesByMethod[type]); + } }) } diff --git a/src/navigation/checkout/components/PaymentMethodIcon.js b/src/navigation/checkout/components/PaymentMethodIcon.js index de793ccd2..b7b153476 100644 --- a/src/navigation/checkout/components/PaymentMethodIcon.js +++ b/src/navigation/checkout/components/PaymentMethodIcon.js @@ -1,7 +1,9 @@ import React from 'react'; -import { Icon } from 'native-base'; +import { Image } from 'react-native'; +import { Box, Icon } from 'native-base'; import Foundation from 'react-native-vector-icons/Foundation'; import Svg, { Path, G } from 'react-native-svg'; +import ConecsIcon from './PaymentMethodIcon/ConecsIcon'; const icons = { card: 'credit-card', @@ -19,9 +21,39 @@ const PaymentMethodIcon = ({ type }) => { />) } + if (type === 'conecs') { + return ( + + + + ) + } + + if (type === 'restoflash') { + return ( + + + + ) + } + + if (type === 'swile') { + return ( + + + + ) + } + if (type === 'edenred' || type === 'edenred+card') { return ( - + { x={0} y={0} fill={ '#000000' } + viewBox="0 0 413.24 265.47" > ( + + + + + + + + + + + + +) + +export default SvgComponent diff --git a/src/navigation/checkout/components/PaymentMethodPicker.js b/src/navigation/checkout/components/PaymentMethodPicker.js index 7efca5391..ea46920be 100644 --- a/src/navigation/checkout/components/PaymentMethodPicker.js +++ b/src/navigation/checkout/components/PaymentMethodPicker.js @@ -16,7 +16,7 @@ const styles = StyleSheet.create({ marginBottom: 10, flexDirection: 'row', alignItems: 'center', - justifyContent: 'center', + justifyContent: 'space-between', }, }); diff --git a/src/navigation/index.js b/src/navigation/index.js index 2958711d1..6cabb569a 100644 --- a/src/navigation/index.js +++ b/src/navigation/index.js @@ -53,6 +53,8 @@ import CheckoutMoreInfos from './checkout/MoreInfos'; import CheckoutPayment from './checkout/Payment'; import CheckoutProductDetails from './checkout/ProductDetails'; import CheckoutSummary from './checkout/Summary'; +import CheckoutPaygreenReturn from './checkout/PaygreenReturn'; +import CheckoutPaygreenCancel from './checkout/PaygreenCancel'; import CheckoutLoopeat from './checkout/Loopeat'; import CheckoutRestaurant from './checkout/Restaurant'; @@ -114,6 +116,8 @@ export default { CheckoutPaymentMethodCashOnDelivery, CheckoutPaymentMethodEdenred, CheckoutLoopeat, + CheckoutPaygreenReturn, + CheckoutPaygreenCancel, AccountHome, AccountAddressesPage, AccountOrdersPage, diff --git a/src/navigation/navigators/CheckoutNavigator.js b/src/navigation/navigators/CheckoutNavigator.js index 107a91827..a81ea2c35 100644 --- a/src/navigation/navigators/CheckoutNavigator.js +++ b/src/navigation/navigators/CheckoutNavigator.js @@ -352,6 +352,20 @@ const DefaultNav = () => { title: i18n.t('ZERO_WASTE'), }} /> + + ); }; diff --git a/src/redux/Checkout/actions.js b/src/redux/Checkout/actions.js index b5f9cac6f..fb9541656 100644 --- a/src/redux/Checkout/actions.js +++ b/src/redux/Checkout/actions.js @@ -1099,7 +1099,8 @@ export function canProceedWithPayment(cart) { export function checkout( cardholderName, savedPaymentMethodId = null, - saveCard = false + saveCard = false, + paygreenPaymentOrderID = null ) { return async (dispatch, getState) => { dispatch(checkoutRequest()); @@ -1112,6 +1113,27 @@ export function checkout( const httpClient = selectHttpClient(getState()); + if (paygreenPaymentOrderID) { + httpClient + .put( + cart['@id'] + '/pay', + { + paymentOrderId: paygreenPaymentOrderID + }, + { + headers: selectCheckoutAuthorizationHeaders( + getState(), + cart, + token, + ), + }, + ) + .then(o => dispatch(handlePaymentSuccess(o))) + .catch(e => dispatch(handlePaymentFailed(e))); + + return; + } + if (isFree(cart)) { httpClient .put( @@ -1902,7 +1924,7 @@ export function setPaymentMethod(paymentMethod, cb) { // TODO Use the payments returned // https://github.com/coopcycle/coopcycle-app/issues/1925 dispatch(updateCartSuccess(cart)); - cb() + cb(res) }) .catch(e => dispatch(checkoutFailure(e))); };