1

I'm creating a react native app and I need to do payment with stripe. Is there any way to do it with or without using any third-party libraries? And I am able to create a Token with fetch method by accessing stripe API with the following code snippet.

Code Snippet

    var cardDetails = {
              'card[number]': this.state.cardData.values.number.replace(/ /g, ''),
              'card[exp_month]': this.state.cardData.values.expiry.split('/')[0],
              'card[exp_year]': this.state.cardData.values.expiry.split('/')[1],
              'card[cvc]': this.state.cardData.values.cvc
            };
         
            var formBody = [];
            for(var property in cardDetails){
                var encodedKey = encodeURIComponent(property);
                var encodedValue = encodeURIComponent(cardDetails[property]);
                formBody.push(encodedKey + "=" + encodedValue);
            }
            formBody = formBody.join("&");

            fetch('https://api.stripe.com/v1/tokens', {
                method: 'POST',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Authorization': 'Bearer '+ STRIPE_PUBLISHABLE_KEY
                 },
                body: formBody
            })
            .then(responseJson => {
                responseJson.json().then(solved=>{
                    cardToken =solved.id;
})

This is what I tried.

Here I used the react-native-credit-card-input library for taking credit card detail. I am new to react-native. And I don't know how to implement the code after this. I am able to get the token from the stripe by accessing 'https://api.stripe.com/v1/tokens' this URL with the above code snippet. But when I am going to create a charge with that token it gives me an error ('https://api.stripe.com/v1/charges'). What is the correct flow to create a payment in stripe with react-native?

import React, {Component} from 'react';
import {
  View,
  Text,
  TouchableOpacity,
  TextInput,
  Platform,
  StyleSheet,
  StatusBar,
  Alert,
  Image,
  ScrollView,
  Animated,
  Dimensions,
  Modal,
} from 'react-native';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import Feather from 'react-native-vector-icons/Feather';

import {
    CreditCardInput,
    LiteCreditCardInput,
  } from 'react-native-credit-card-input';

class stripePay extends Component {

    constructor(props) {
        super(props);
        this.state = { cardData: { valid: false },tokenCRD:'' };
      }
  
  ContFunction = () => {
    this.getCreditCardToken();
  };

    getCreditCardToken = () => {

        var cardToken;
        var STRIPE_PUBLISHABLE_KEY = 'pk_test_*****************';
        var STRIPE_SECRET_KEY ='sk_test_*************************';

         var cardDetails = {
              'card[number]': this.state.cardData.values.number.replace(/ /g, ''),
              'card[exp_month]': this.state.cardData.values.expiry.split('/')[0],
              'card[exp_year]': this.state.cardData.values.expiry.split('/')[1],
              'card[cvc]': this.state.cardData.values.cvc
            };
          var amount= 1*100;
              
            var formBody = [];
            for(var property in cardDetails){
                var encodedKey = encodeURIComponent(property);
                var encodedValue = encodeURIComponent(cardDetails[property]);
                formBody.push(encodedKey + "=" + encodedValue);
            }
            formBody = formBody.join("&");

            fetch('https://api.stripe.com/v1/tokens', {
                method: 'POST',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Authorization': 'Bearer '+ STRIPE_PUBLISHABLE_KEY
                 },
                body: formBody
            })
            .then(responseJson => {
                // console.log(responseJson);
                responseJson.json().then(solved=>{
                    cardToken =solved.id;
                    // console.log(cardToken);
                    
                    var paymentbody = {
                      amount: amount,
                      currency: 'usd',
                      description: 'Example charge',
                      source: cardToken,
                      //source: "tok_visa",
                    }

                    if(cardToken!=""){
                      //console.log(cardToken);

                      fetch('https://api.stripe.com/v1/charges', {
                          method: 'POST',
                          headers: {
                            'Accept': 'application/json',
                            'Content-Type': 'application/x-www-form-urlencoded',
                            'Authorization': 'Bearer '+ STRIPE_SECRET_KEY
                          },
                          body:paymentbody
                        })
                          .then(response => response.json())
                          .then(responseJson => {
                            console.log(responseJson);
                          })
                          .catch(error => {
                            console.error(error);
                          });

                    }else{
                      console.log("Error")
                    }
                    
                });
            })
            .catch(error => {
                console.error(error);
            });      
    }

  render() {
    return (
      <View style={styles.container}>
        <StatusBar backgroundColor="#009387" barStyle="light-content" />
        <View style={styles.header}>
          <Text style={styles.text_header}>Testing Stripe Payment!</Text>
        </View>
        <View style={[styles.footer]}>

        <View style={styles.cardContainer}>
              <CreditCardInput
                autoFocus
                requiresName
                requiresCVC
                requiresPostalCode

                labelStyle={styles.label}
                inputStyle={styles.input}
                validColor={'black'}
                invalidColor={'red'}
                placeholderColor={'darkgray'}
                onFocus={this._onFocus}
                // onChange={this._onChange}
                onChange={(cardData) => this.setState({ cardData })}
              />
            </View>

            <View style={styles.button1}>
              <TouchableOpacity
                style={styles.btnCon}
                onPress={() => this.ContFunction()}>
                <View
                  style={styles.btnCon}>
                  <Text style={[styles.textCon]}>Pay Now</Text>
                </View>
              </TouchableOpacity>
            </View>
          
        </View>
      </View>
    );
  }
}

export default stripePay;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#009387',
  },
  header: {
    flex: 1,
    justifyContent: 'flex-end',
    paddingHorizontal: 20,
    paddingBottom: 30,
  },
  text_header: {
    color: '#fff',
    fontWeight: 'bold',
    fontSize: 30,
  },
  footer: {
    flex: 3,
    backgroundColor: '#fff',
    borderTopLeftRadius: 30,
    borderTopRightRadius: 30,
    paddingHorizontal: 20,
    paddingVertical: 30,
  },
  cardContainer: {
    backgroundColor: '#fff',
    marginTop: 60,
  },
  label: {
    color: 'black',
    fontSize: 12,
  },
  input: {
    fontSize: 16,
    color: 'black',
  },
  button1: {
    alignItems: 'center',
    marginTop: 40,
    // width:'80%',
  },
  btnCon: {
    width: '80%',
    height: 50,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 10,
    backgroundColor: '#00b530',
  },
  textCon: {
    fontSize: 18,
    fontWeight: 'bold',
    color: 'white',
  },
});

I got the following error.

Error

Sidath
  • 379
  • 1
  • 9
  • 25

1 Answers1

2

All stripe payments can be handled through api using fetch, so there is no need in using 3rd party libraries.

You need to create a customer, add the card to the customer, then create the payment, create one-time-use card token and confirm the payment with the card token.

Payment verification is handled through the link in response, which is supposed to be opened in browser, where the user can confirm the payment manually. In this case, use the PaymentIntents api.

Václav Ryska
  • 215
  • 2
  • 7