Payment

https://stripe.com/

https://www.npmjs.com/package/react-stripe-checkout

https://stripe.com/docs/api#create_charge

Payment Flow

Payment Flow

Client Side

Stripe Dialog

React -> Stripe

pending token from Stripe

React -> Node

Result

Payment Cmp

$npm install --save react-stripe-checkout
import React, { Component } from 'react';
import StripeCheckout from 'react-stripe-checkout';
import { connect } from 'react-redux';
import * as actions from '../actions';

class Payments extends Component {
  render() {
    return (
      <StripeCheckout
        name="Emaily"
        description="$5 for 5 email credits"
        amount={500}
        token={token => this.props.handleToken(token)}
        // token={token => console.log(token)}
        stripeKey={process.env.REACT_APP_STRIPE_KEY}
      >
        <button className="btn">
          Add Credits
        </button>
      </StripeCheckout>
    );
  }
}

export default connect(null, actions)(Payments);

callback hanlde

Action

import axios from 'axios';
import { FETCH_USER } from './types';

export const handleToken = token => async dispatch => {
  const res = await axios.post('/api/stripe', token);

  dispatch({ type: FETCH_USER, payload: res.data });
};

action

export const FETCH_USER = 'fetch_user';

type.js

Header Cmp

import Payments from './Payments';
class Header extends Component {
    renderContent() {
        switch (this.props.auth) {
          case null:
            return;
          case false:
            return <li><a href="/auth/google">Login With Google</a></li>;
          default:
            return [
              <li key="1"><Payments /></li>,
              <li key="2" style={{ margin: '0 10px' }}>
                Credits: {this.props.auth.credits}
              </li>,
              <li key="3"><a href="/api/logout">Logout</a></li>
            ];
        }
    }
    render() {
        return (
            <nav>
                <div className="nav-wrapper">
                  <ul className="right">
                    {this.renderContent()}
                  </ul>
                </div>
            </nav>
        )
    }
}
const mapStateToProps = ({ auth }) => {return { auth }}  
export default connect(mapStateToProps)(Header)

Login

Server Side

1. pay post(with pending token)

2. send to Stripe

3. callback -> add credit to User

 

check: if User is login

Handle Payment

 

Do sth..

$npm install --save stripe
$npm install --save body-parser
const mongoose = require('mongoose');
const { Schema } = mongoose;

const userSchmea = new Schema({
    googleId: String,
    credits: { type: Number, default: 0 }
})

mongoose.model('users', userSchmea);
app.use(bodyParser.json());
module.exports = (req, res, next) => {
  if (!req.user) {
    return res.status(401).send({ error: 'You must log in!' });
  }

  next();
};

User Model

index.js

Middleware(requireLogin.js)

Handle Payment

const keys = require('../config/key');
const stripe = require('stripe')(keys.stripeSecretKey);
const requireLogin = require('../middlewares/requireLogin');

module.exports = app => {
  app.post('/api/stripe', requireLogin, async (req, res) => {
    const charge = await stripe.charges.create({
      amount: 500,
      currency: 'usd',
      description: '$5 for 5 credits',
      source: req.body.id
    });
    req.user.credits += 5;
    const user = await req.user.save();

    res.send(user);
  });
};

Pending Token

require('./routes/billngRoutes')(app);

Deployment Note

if (process.env.NODE_ENV === 'production') {
  // Express will serve up production assets
  // like our main.js file, or main.css file!
  app.use(express.static('client/build'));

  // Express will serve up the index.html file
  // if it doesn't recognize the route
  const path = require('path');
  app.get('*', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
  });
}

Deployment Note

"scripts": {
    "heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client 
                        && npm run build --prefix client"
}

Payment Flow X React X Node X Mongo

By Matt Jhou

Payment Flow X React X Node X Mongo

  • 301