Lists and Get Stripe Product / Plan / Price by using Gatsby
Sometimes, we use Stripe to manage the product/plan data master. And we want to show these product/plan data o […]
目次
Sometimes, we use Stripe to manage the product/plan data master. And we want to show these product/plan data on our own website without posting to another CMS or data source.
When using Gatsby, we can get it by using Source plugin
Prepare: Get a limited API Key
We can get the Stripe data by using the Stripe API key, but the basic API Secret has huge permissions.
In this case, we just read product and plan or price data from API, we don’t have to get any other permission.
So, I recommend creating a Limited Key on the Stripe Dashboard.
When we want to get Stripe products/plans/prices, we must add reading permission for this resource. And, need to allow to read the PaymentIntents
.
I’m not sure why, but the Stripe API will throw a permission error when disallow to access the PaymentIntents
resource.
Add and configure gatbsy-source-stripe
plugin
We can get Stripe data by using this plugin.
$ npm i -D gatsby-source-stripe
And should define the configurations in the gatsby-config.js
module.exports = {
plugins: [
`gatsby-plugin-typescript`,
{
resolve: `gatsby-source-stripe`,
options: {
objects: ['Product', 'Plan'],
secretKey: process.env.STRIPE_API_SECRET,
}
},
...
In this example, the source plugin will get the Product and Plan resources from Stripe.
Check and test the GraphQL Query and Schema
After updating the gatsby-conig.js
, we can execute gatsby develop
command.
When we run the command, we can access the GraphiQL console.And the URL is like a http://localhost:8000/__graphql
.
Then, we can test the GraphQL query on this console, and use the query into Gatsby React component.
Get Stripe Plans by product
If you want to list the plans by product ids? We need to write any code into gatsby-node.js
import { SourceNodesArgs } from "gatsby";
import Stripe from "stripe";
const nodeType = 'CustomProductWithPlans'
export const sourceNodes = async (args: SourceNodesArgs): Promise<void> => {
const {
createNodeId,
actions: {
createNode,
},
createContentDigest,
} = args
const stripe = new Stripe(process.env.STRIPE_API_SECRET, {
apiVersion: '2020-08-27'
})
const publishableProductIds = [
'prod_A',
'prod_B',
]
const products = await Promise.all(publishableProductIds.map(async productId => {
try {
const product = await stripe.products.retrieve(productId)
return product
} catch (e) {
if (e.code === 'resource_missing' && /prod/.test(productId)) {
return null;
}
console.log(e)
throw e
}
})).then(data => data.filter(Boolean))
const datasets = await Promise.all(products.map(async (product) => {
if (!product) return null;
const {data: plans } = await stripe.plans.list({
product: typeof product === 'string' ? product : product.id,
active: true
})
return {
...product,
plans
}
}))
datasets.forEach(product => {
if (!product) return;
const data = {
...product,
id: createNodeId(`${nodeType}${product.id}`),
productId: product.id,
}
createNode({
...data,
internal: {
type: nodeType,
contentDigest: createContentDigest(data)
}
})
})
return undefined;
}