如何将Stripe与React和Firebase结合使用

时间:2020-06-05 20:29:48

标签: reactjs firebase google-cloud-firestore stripe-payments

所以我将firebase用作数据库和托管服务,并且已经在React中编写了该应用程序。

现在,我正在尝试将Stripe添加到应用程序中,以便向客户收费。但是有一个问题,Stripe似乎需要一个单独的服务器,这有点问题,因为我正在使用Firebase。

我已经阅读了文档(在这里-https://firebase.google.com/docs/use-cases/payments)并观看了来自Firebase的视频(在这里-https://www.youtube.com/watch?v=BrLTF4QdRrM和在这里-https://www.youtube.com/watch?v=BrLTF4QdRrM),但我仍然迷路。

我不知道我应该把Stripe Publishable Key包含在什么地方,我已经陷入了一个难题,接下来的几个小时我将不得不花费最后的几个小时来消除。

如果您可以为我提供一个简单指南的方向,或者只是告诉我可发布密钥需要去的地方,那将非常有帮助!

这可能会给您带来极大的困扰,但这是我创建的创建条带客户和条带费等的代码。

mport * as stripe from "stripe";
import * as functions from "firebase";
import getFirestoreDb from "../firebase/firestore/getFirestoreDb";


// import {firestore} from "@firebase/firestore/dist/packages/firestore/test/util/api_helpers";
// const admin = require('firebase-admin');
// admin.initializeApp();


// const logging = require('@google-cloud/logging')();
// const currency = functions.config().stripe.currency || 'USD';

const db = getFirestoreDb();

//START CUSTOMER CHARGE //
// Charge the Stripe customer whenever an amount is created in Cloud Firestore

export const createStripeCharge = functions.firestore
  .document('stripe_customers/{userId}/charges/{autoId}')
  .onCreate(async ( snap, context) => {
    const val = snap.data();
    try {
      //Look up the Stripe customer id written in createStripeCustomer
      const snapshot = await
        db.collection('stripe_customers')
        .doc(context.params.userId).get();
      const snapval = snapshot.data();
      const customer = snapval.customer_id;

      // Create a charge using the pushId as the idempotency key
      // protecting against double charges
      const amount = val.amount;
      const idempotencyKey = context.params.id;
      const currency = "USD";
      const charge = {amount, currency, customer};
      if (val.source !== null) {
        charge.source = val.source;
      }
      // setSourceOrDefault(charge, snap.data().source)
      const response = await stripe.charges.create(charge, {idempotency_key: idempotencyKey} );
      //if the result is successful, write it back to the database
      return snap.ref.set(response, {merge:true});
    } catch(error)  {
      // We want to capture errors and render them in a user-friendly way, while
      // still logging an exception with StackDriver
      await snap.ref.set({error: userFacingMessage(error)}, {merge:true});
      // return reportError(error, {user: context.params.userId});
    }
  });

// END CUSTOMER CHARGE //

// When a user is created, register them with Stripe
export const createStripeCustomer = functions.auth.user().onCreate(async (user) => {
  const customer = await stripe.customers.create({email: user.email});
  return db.collection('stripe_customers').doc(user.uid).set({customer_id: customer.id});
});

// Add a payment source (card) for a user by writing a stripe payment source token to Cloud Firestore
export const addPaymentSource = functions.firestore.document('/stripe_customers/{userId}/tokens/{pushId}').onCreate(async (snap, context) => {
  const source = snap.data();
  const token = source.token;
  if (source === null){
    return null;
  }

  try {
    const snapshot = await db.collection('stripe_customers').doc(context.params.userId).get();
    const customer =  snapshot.data().customer_id;
    const response = await stripe.customers.createSource(customer, {source: token});
    return db.collection('stripe_customers').doc(context.params.userId).collection("sources").doc(response.fingerprint).set(response, {merge: true});
  } catch (error) {
    await snap.ref.set({'error':userFacingMessage(error)},{merge:true});
    // return reportError(error, {user: context.params.userId});
  }
});

// When a user deletes their account, clean up after them
export const cleanupUser = functions.auth.user().onDelete(async (user) => {
  const snapshot = await db.collection('stripe_customers').doc(user.uid).get();
  const customer = snapshot.data();
  await stripe.customers.del(customer.customer_id);
  return db.collection('stripe_customers').doc(user.uid).delete();
});

// To keep on top of errors, we should raise a verbose error report with Stackdriver rather
// than simply relying on console.error. This will calculate users affected + send you email
// alerts, if you've opted into receiving them.
// // [START reporterror]
// function reportError(err, context = {}) {
//   // This is the name of the StackDriver log stream that will receive the log
//   // entry. This name can be any valid log stream name, but must contain "err"
//   // in order for the error to be picked up by StackDriver Error Reporting.
//   const logName = 'errors';
//   const log = logging.log(logName);
//
//   // https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/MonitoredResource
//   const metadata = {
//     resource: {
//       type: 'cloud_function',
//       labels: {function_name: process.env.FUNCTION_NAME},
//     },
//   };
//
//   // https://cloud.google.com/error-reporting/reference/rest/v1beta1/ErrorEvent
//   const errorEvent = {
//     message: err.stack,
//     serviceContext: {
//       service: process.env.FUNCTION_NAME,
//       resourceType: 'cloud_function',
//     },
//     context: context,
//   };
//
//   // Write the error log entry
//   return new Promise((resolve, reject) => {
//     log.write(log.entry(metadata, errorEvent), (error) => {
//       if (error) {
//         return reject(error);
//       }
//       return resolve();
//     });
//   });
// }
// [END report error]


function userFacingMessage(error) {
  return error.type ? error.message : 'An error has occurred, developers have been alerted';
}

stripe.setPublishableKey("STRIPE_KEY");

1 个答案:

答案 0 :(得分:0)

您必须在客户端设置可发布密钥。

例如,使用React Native和tipsi-stripe(条纹客户端sdk),您可以执行以下操作:

import stripe from 'tipsi-stripe'

stripe.setOptions({
    publishableKey: 'YOUR-PUBLISHABLE-KEY',
})

您只需要使用publishableKey初始化要使用的条带客户端sdk。