I'm trying to integrate Stripe payment into React Native application and I'm using code for reference that worked on React js project but I can't seem to get it working here. I'm still newbie so any help would be really appreciated.
import { CardElement, useElements, useStripe } from "#stripe/react-stripe-js"
import axios from "axios"
import React, { useState } from 'react'
import { View, Text, Button } from 'react-native'
const CARD_OPTIONS = {
iconStyle: "solid",
style: {
base: {
iconColor: "#c4f0ff",
fontWeight: 500,
fontFamily: "Roboto, Open Sans, Segoe UI, sans-serif",
fontSize: "16px",
fontSmoothing: "antialiased",
":-webkit-autofill": { color: "#fce883" },
"::placeholder": { color: "#87bbfd" }
},
invalid: {
iconColor: "#ffc7ee",
color: "#ffc7ee"
}
}
}
export default function PaymentForm() {
const [success, setSuccess ] = useState(false)
const stripe = useStripe()
const elements = useElements()
const handleSubmit = async () => {
const {error, paymentMethod} = await stripe.createPaymentMethod({
type: "card",
card: elements.getElement(CardElement)
})
if(!error) {
try {
const {id} = paymentMethod
const response = await axios.post("http://localhost:4000/payment", {
amount: 1000,
id
})
if(response.data.success) {
console.log("successful payment")
setSuccess(true)
}
} catch (error) {
console.log("Error", error)
}
}else {
console.log(error.message)
}
}
return (
<>
{!success ?
<View>
<CardElement options={CARD_OPTIONS}/>
<Button
title="Pay"
onPress={handleSubmit} >
</Button>
<Text>Hello1</Text>
</View>
:
<View>
<Text>Purchase successful</Text>
</View>
}
</>
)
}
The Error I'm getting:
View config getter callback for component 'div' must be a function (received 'undefined'). Make sure to start component names with a capital letter.
And from experimenting I noticed that when commenting out
<CardElement />
it got rid of error.
Unfortunately this use of the CardElement is not possible in React Native without something to act as a bridge to the native components.
In a recent issue of the Stripe Dev newsletter, there is a form to share details of your integration and express interest in hearing more about Stripe's work with React Native. I strongly suggest filling that out to explain what you're working on!
Related
Why is CoinbaseWalletConnector not working (wagmi)?
I use the wagmi library to create a dap, Wallet connect does not connect during work. All other wallets work correctly, Wallet connect gives an error.
Error:
Uncaught ReferenceError: Buffer is not defined
at Object.__ (QRCode.js:27:1)
enter image description he
App.
In App I import all the necessary modules, creating a client
//App
import { WagmiConfig, createClient } from "wagmi";
import { configureChains } from "wagmi";
import { avalanche, bsc, mainnet } from '#wagmi/core/chains'
import { infuraProvider } from "wagmi/providers/infura";
import { publicProvider } from "wagmi/providers/public";
import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet";
import { MetaMaskConnector } from "wagmi/connectors/metaMask";
import { WalletConnectConnector } from 'wagmi/connectors/walletConnect'
// API key for Ethereum node
// Two popular services are Infura (infura.io) and Alchemy (alchemy.com)
const infuraId = process.env.INFURA_ID;
const defaultChains = [mainnet, avalanche, bsc]
// Configure chains for connectors to support
const { chains } = configureChains(defaultChains, [
infuraProvider({ infuraId }),
publicProvider(),
]);
// Set up connectors
export const connectors = [
new CoinbaseWalletConnector({
chains,
options: {
appName: "wagmi demo",
qrcode: true,
},
}),
new WalletConnectConnector({
chains,
options: {
infuraId,
qrcode: true,
},
}),
new MetaMaskConnector({
chains,
}),
];
const client = createClient({
autoConnect: false,
connectors,
});
function App() {
return (
<>
<WagmiConfig client={client}>
<Home />
</WagmiConfig>
</>
);
}
My component
In my main component I write onclick() to handle wallets
//My component
import { useConnect } from "wagmi";
const Component = (props) => {
const { connect, connectors } = useConnect();
return (
<>
<WalletButton img={metaMask}
title={"MetaMask"}
onPress={() => { connect({ connector: connectors[2] }) }}
/>
<WalletButton img={coinbase}
title={"Coinbase wallet"}
onPress={() => { connect({ connector: connectors[0] }) }}
/>
<WalletButton img={walletConnectImg}
title={"Wallet connect"}
onPress={() => { connect({ connector: connectors[1] }) }}/>
</>
)
}
Who faced a similar problem? Help XD
I have integrated a stripe #stripe/react-stripe-js: ^1.8.1 into my project. Stripe form working fine it popup a payment form but when I enter the payment information in the form and press the submit button, these errors return. it returns this errorsIntegrationError: Invalid value for stripe.confirmPayment():. I've tried but I was not able to resolve this issue. Could someone please help me how to resolve this issue?
import { CardElement, useElements, useStripe } from "#stripe/react-stripe-js";
import PropTypes from "prop-types";
import React, { useState } from "react";
import "./style.css";
const CARD_OPTIONS = {
iconStyle: "solid",
style: {
base: {
iconColor: "#dfe1e7",
color: "#000",
fontWeight: 500,
fontFamily: "Roboto, Open Sans, Segoe UI, sans-serif",
borderColor: "#000",
fontSize: "16px",
fontSmoothing: "antialiased",
":-webkit-autofill": { color: "#dfe1e7" },
"::placeholder": { color: "#c6c6c6" },
},
invalid: {
iconColor: "#000",
color: "#000",
},
},
};
export function CheckOutForm(props) {
const [success, setSuccess] = useState(false);
const stripe = useStripe();
const elements = useElements();
console.log("## props", elements, props);
const handleSubmit = async (event) => {
event.preventDefault();
const result = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: "https://example.com/order/123/complete",
},
});
if (result.error) {
console.log(result.error.message);
} else {
setSuccess(true);
}
};
return (
<>
{!success ? (
<form className="container" onSubmit={handleSubmit}>
<fieldset className="FormGroup">
<div className="FormRow">
<CardElement options={CARD_OPTIONS} />
</div>
</fieldset>
<button className="SubmitButton">Pay</button>
</form>
) : (
<div>
<h2>
You just bought a sweet spatula congrats this is the best decision
of you are life
</h2>
</div>
)}
</>
);
}
CheckOutForm.prototypes = {
props: PropTypes.object,
paymentInformation: PropTypes.string,
};
const result = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: "https://example.com/order/123/complete",
},
});
Your error is here, confirmPayment takes 2 params, your passing in one because of the unnessary curly braces starting before elements
const result = await stripe.confirmPayment(
elements,
confirmParams: {
return_url: "https://example.com/order/123/complete"
}
);
I am pretty sure am supplying a function to the LottieView component, but am getting the aforementioned console warning error: Failed prop type: Invalid prop onAnimationFinish of type object supplied to LottieView, expected a function., telling me I supplied an object. Here below is part of my code affiliated with the issue:
import React from "react";
import { View, StyleSheet, Modal } from "react-native";
import * as Progress from "react-native-progress";
import LottieView from "lottie-react-native";
import colors from "../config/colors";
function UploadScreen(onDone, progress = 0, visible = false) {
return (
<Modal visible={visible}>
<View style={styles.container}>
{progress < 1 ? (
<Progress.Bar
color={colors.primary}
progress={parseInt(progress)}
width={200}
/>
) : (
<LottieView
autoPlay
loop={false}
onAnimationFinish={onDone}
source={require("../assets/animations/done.json")}
style={styles.animation}
/>
)}
</View>
</Modal>
);
}
const styles = StyleSheet.create({
animation: { width: 150 },
container: {
alignItems: "center",
flex: 1,
justifyContent: "center",
},
});
export default UploadScreen;
And the component consuming the UploadScreen component is as follows:
import { StyleSheet } from "react-native";
import React, { useState } from "react";
import * as Yup from "yup";
import {
Form,
FormField,
FormImagePicker,
FormPicker as Picker,
SubmitButton,
} from "../components/forms";
import listingsApi from "../api/listings";
import Screen from "../components/Screen";
import CategoryPickerItem from "../components/CategoryPickerItem";
import useLocation from "../custom_hooks/useLocation";
import UploadScreen from "./UploadScreen";
const validationSchema = Yup.object().shape({
title: Yup.string().required().min(1).label("Title"),
price: Yup.number().required().min(1).max(10000000).label("Price"),
description: Yup.string().label("Description"),
category: Yup.object().required().nullable().label("Category"),
images: Yup.array().min(1, "Please select at least one image!"),
});
const categories = [
{
backgroundColor: "#fc5c65",
icon: "floor-lamp",
label: "Furniture",
value: 1,
},
{
backgroundColor: "#fd9644",
icon: "car",
label: "Cars",
value: 2,
},
];
function ListingEditScreen() {
const userLocation = useLocation();
const [uploadVisible, setUploadVisible] = useState(false);
const [progress, setProgress] = useState(0);
const handleSubmit = async (listing, { resetForm }) => {
setProgress(0);
setUploadVisible(true);
const result = await listingsApi.addListing(
{ ...listing, userLocation },
(progress) => setProgress(progress)
);
if (!result.ok) {
setUploadVisible(false);
return alert("Could not save the listing");
}
resetForm();
};
return (
<Screen style={styles.container}>
<UploadScreen
onDone={() => setUploadVisible(false)}
progress={progress}
visible={uploadVisible}
/>
</Screen>
);
}
export default ListingEditScreen;
You're not destructuring your props. The first argument to UploadScreen is the entire props object:
// onDone is your entire props object here.
function UploadScreen(onDone, progress = 0, visible = false) {
Add braces to pull out specific props:
// add the curlies to extract specific props
function UploadScreen({onDone, progress = 0, visible = false}) {
Destructure the props
function UploadScreen({onDone, progress, visible}) {
I'm trying to build a web app with react-admin and need to push data to the redux store. I read the React-admin docs (https://marmelab.com/react-admin/Actions.html) and when I try to do that, I get Failures.
Here is my code
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { withStyles, MuiThemeProvider, createMuiTheme } from '#material-ui/core/styles';
import {
Menu,
Notification,
Sidebar,
setSidebarVisibility,
} from 'react-admin';
import {kidsLoad} from './customActions/KidsActions'
import AppBar from './MyAppBar';
const styles = theme => ({
root: {
display: 'flex',
flexDirection: 'column',
zIndex: 1,
minHeight: '100vh',
backgroundColor: theme.palette.background.default,
position: 'relative',
},
appFrame: {
display: 'flex',
flexDirection: 'column',
overflowX: 'auto',
},
contentWithSidebar: {
display: 'flex',
flexGrow: 1,
},
content: {
display: 'flex',
flexDirection: 'column',
flexGrow: 2,
padding: theme.spacing.unit * 3,
marginTop: '1em',
paddingLeft: 5,
},
});
class MyLayout extends Component {
componentWillMount() {
this.props.setSidebarVisibility(true);
}
componentDidMount(){
const { kidsLoad, record } = this.props;
kidsLoad({data: "HELLOOOOOOOOOOOO!!!!!"})
}
render() {
const {
children,
classes,
dashboard,
isLoading,
logout,
open,
title,
} = this.props;
return (
<div className={classes.root}>
<div className={classes.appFrame}>
<AppBar title={title} open={open} logout={logout} />
<main className={classes.contentWithSidebar}>
<div className={classes.content}>
{children}
</div>
</main>
<Notification />
</div>
</div>
);
}
}
MyLayout.propTypes = {
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
dashboard: PropTypes.oneOfType([
PropTypes.func,
PropTypes.string,
]),
isLoading: PropTypes.bool.isRequired,
// logout: componentPropType,
setSidebarVisibility: PropTypes.func.isRequired,
title: PropTypes.string.isRequired,
kidsLoad: PropTypes.func,
};
const mapStateToProps = state => ({ isLoading: state.admin.loading > 0 });
export default connect(mapStateToProps, { setSidebarVisibility, kidsLoad })(withStyles(styles)(MyLayout));
I did everything like in the documentation (https://marmelab.com/react-admin/Actions.html).
What did I do wrong?
How do you add data to the store in this framework?
This is going to be a quick answer that I leave for further improvement.
If I understand your question correctly you got some of your resources (entities) updated and you want react-admin to know about it and update its store accordingly triggering updates in app views if necessary.
The first thing we have to get is the dispatch function of the react-admin store. In my case, the source of resource update was a React component, so I used withDataProvider decorator to receive a reference to the dispatch function.
Once you have the dispatch function you dispatch, for example, CRUD_UPDATE_SUCCESS action for a particular resource update in the react-admin store.
import { CRUD_UPDATE_SUCCESS, FETCH_END, UPDATE } from 'react-admin';
dispatch({
type: CRUD_UPDATE_SUCCESS,
payload: { data },
meta: {
resource,
notification: {
body: 'ra.notification.dataSaved',
level: 'info'
},
fetchResponse: UPDATE,
fetchStatus: FETCH_END
}
});
You can also use action creators from react-admin. Like showNotification, for example.
import { showNotification } from 'react-admin';
dispatch(showNotification(errorMessage, 'warning', { autoHideDuration: 10000 }));
A bit more consistent piece of code here to show how all this can work together. The Updater component here renders its child components passing them a resource record and subscribes for their onSubmit callback to perform entity saving and updating react-admin store.
import React from 'react';
import {
CRUD_UPDATE_SUCCESS, FETCH_END, UPDATE, withDataProvider, showNotification
} from 'react-admin';
class Updater extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleUpdate(record) {
const { resource, dataProvider, dispatch } = this.props;
const payload = {
id: record.id,
};
payload.data = {...record};
return new Promise((resolve, reject) => {
dataProvider(UPDATE, resource, payload)
.then(({data}) => {
dispatch({
type: CRUD_UPDATE_SUCCESS,
payload: { data },
meta: {
resource,
notification: {
body: 'ra.notification.dataSaved',
level: 'info'
},
fetchResponse: UPDATE,
fetchStatus: FETCH_END
}
});
resolve(data);
})
.catch(e => {
const errorMessage = e.message || e;
this.setState({ errorMessage });
dispatch(
showNotification(errorMessage, 'warning', { autoHideDuration: 10000 })
);
reject(errorMessage);
});
});
}
render() {
const { record, children } = this.props;
const { errorMessage } = this.state;
return React.Children.only(React.cloneElement(children, {
record,
errorMessage,
onUpdate: this.handleUpdate
}));
}
}
export default withDataProvider(Updater);
HTH,
Ed
import React, { Component } from 'react';
import {
AppRegistry,
Button,
StyleSheet,
View,
requireNativeComponent,
} from 'react-native';
import Sketch from 'react-native-sketch';
const styles = StyleSheet.create({
container: {
flex: 1,
},
sketch: {
height: 250, // Height needed; Default: 200px
},
});
export default class paintChalledgeNative extends Component {
constructor(props) {
super(props);
this.clear = this.clear.bind(this);
this.onReset = this.onReset.bind(this);
this.onSave = this.onSave.bind(this);
this.onUpdate = this.onUpdate.bind(this);
this.state = {
drawing: null,
};
}
onReset() {
console.log('bye bye drawing');
}
onSave() {
this.sketch.saveImage(this.state.drawing)
.then(data => console.log(data))
.catch(error => console.log(error));
}
onUpdate(base64Image) {
this.setState({ drawing: base64Image });
}
clear() {
this.sketch.clear();
}
render() {
return (
<View style={styles.container}>
<Sketch
fillColor="transparent"
strokeColor="#111111"
strokeThickness={2}
imageType="png"
onReset={this.onReset}
onUpdate={this.onUpdate}
ref={(sketch) => { this.sketch = sketch; }}
style={styles.sketch}
/>
<Button
onPress={this.clear}
title="clear drawing"
/>
<Button
disabled={!this.state.encodedSignature}
onPress={this.onSave}
title="Save drawing"
/>
</View>
);
}
}
AppRegistry.registerComponent('paintChalledgeNative', () => paintChalledgeNative);
building sketch app using 'react-native-sketch' the simulator is running but the sketch feature is not woking at all and the clear button crashes the app with and error in the image , the console is logging 20 similar error msgs to the one below
'In file included from /Users/waltershub/Desktop/paintChalledgeNative/node_modules/react-native-sketch/RNSketch/RNSketch.m:11:
../react-native/React/Base/RCTEventDispatcher.h:18:3: error: redefinition of enumerator 'RCTTextEventTypeChange'
RCTTextEventTypeChange,'
I think it's because you've used the 0.5 version of react-native-sketch, which wasn't compatible with React Native > 0.40. Since then, a new 1.0 version has been published, so maybe you could try again with this one?
(Disclaimer: I'm the maintainer of react-native-sketch)