本文共 8054 字,大约阅读时间需要 26 分钟。
Have you ever woken up in the middle of the night, worried that you are not using the Stripe npm module properly? Probably not, but this article will help put your troubled soul at ease anyway with some interactive Node.js examples that explain how to build an excellent Stripe integration.
您是否曾经在深夜醒来,担心您没有正确使用Stripe npm模块? 可能不是,但是本文将通过一些交互式Node.js示例来帮助您解决麻烦,这些示例解释了如何构建出色的Stripe集成。
Pagination is a necessary evil that saves us from loading too much data, but dealing with it in code can be a pain. Before `v6.11.0`, your Stripe code would look something like this to deal with pagination:
分页是一种必不可少的弊端,它使我们免于加载过多数据,但是用代码处理它可能会很痛苦。 在`v6.11.0`之前,您的Stripe代码看起来像这样来处理分页:
//require Stripe's Node bindingsconst stripe = require("stripe")("rk_test_72wdhn7pifTOWbrtrSNFxhsQ00NrdzPvaC")//get first 100 invoiceslet invoices = await stripe.invoices.list({limit: 100});let numberProcessed = 0;//loop through these invoicesfor(let invoice of invoices.data){ numberProcessed++;}//has_more indicates if we need to deal with paginationwhile(invoices.has_more){ //starting_after will be the the id of the last result invoices = await stripe.invoices.list({limit: 100, starting_after: invoices.data[invoices.data.length -1].id}); //loop through the next 100 for(let invoice of invoices.data){ numberProcessed++; } console.log("Number processed so far: " + numberProcessed);}console.log("Total Number Processed: " + numberProcessed);
With the introduction of auto-pagination in `v6.11.0`, we are now able to have a much more efficient way of paginating:
通过在v6.11.0中引入自动分页功能,我们现在可以拥有更高效的分页方式:
//require Stripe's Node bindingsconst stripe = require("stripe")("rk_test_72wdhn7pifTOWbrtrSNFxhsQ00NrdzPvaC")//get all invoicesconst allInvoices = await stripe.invoices.list({limit: 100}).autoPagingToArray({limit: 10000});console.log("Invoices - " + allInvoices.length);
Note: You need to be running Node.js v10 or above for this.
注意:为此,您需要运行Node.js v10或更高版本。
In Stripe, there are a lot of different objects. A lot of times, when dealing with one type of object, say a subscription; you want to get the product that subscription belongs. To get the product, you need to make an extra call to Stripe as shown here:
在Stripe中,有很多不同的对象。 很多时候,当处理一种类型的对象时,说一个订阅。 您想要获取订阅所属的产品。 要获得产品,您需要对Stripe进行额外的调用,如下所示:
//require Stripe's Node bindingsconst stripe = require("stripe")("rk_test_3U9s3aPLquPOczvc4FVRQKdo00AhMZlMIE")const subscription = await stripe.subscriptions.retrieve("sub_G0zK9485afDl6O");const product = await stripe.products.retrieve(subscription.plan.product);console.log(product.name);
We can effectively avoid this by using the :
我们可以通过使用的来有效地避免这种情况:
//require Stripe's Node bindingsconst stripe = require("stripe")("rk_test_3U9s3aPLquPOczvc4FVRQKdo00AhMZlMIE")//expand the product inside the planconst subscription = await stripe.subscriptions.retrieve("sub_G0zK9485afDl6O", {expand: "plan.product"});console.log(subscription.plan.product.name);
Cutting down on API calls will improve your app's performance and reduce the risk of hitting Stripe's API limits.
减少API调用将提高应用程序的性能,并降低达到Stripe API限制的风险。
Most people with a simple Stripe integration will define a new Stripe connection on the fly without configuring it first like so:
大多数具有简单Stripe集成的人会在运行时定义新的Stripe连接,而无需像这样先进行配置:
const stripe = require("stripe")("STRIPE_SECRET_KEY");
const stripe = require("stripe")("STRIPE_SECRET_KEY");
When scaling your billing system, consider doing the following to improve your integration quality:
扩展计费系统时,请考虑执行以下操作以提高集成质量:
Lock your API version to avoid being affected by API changes
锁定您的API版本,以避免受到API更改的影响
Set to Retry Automatically in case of network failure
设置为在网络故障时自动重试
Define your app information to help the Stripe team
定义您的应用信息以帮助Stripe团队
function createStripeConnection(stripe_api_key){ const Stripe = require("stripe"); const stripe = Stripe(stripe_api_key); stripe.setApiVersion('2019-03-14');//lock API version down to avoid code breaking stripe.setAppInfo({ name: 'Servicebot', version: "1.1.3", //Optional url: 'https://servicebot.io' // Optional }); stripe.setMaxNetworkRetries(3); //retry on network failure return stripe;}const stripe = createStripeConnection("rk_test_72wdhn7pifTOWbrtrSNFxhsQ00NrdzPvaC");console.log(await stripe.invoices.list());
Webhooks play an essential role in most Stripe integrations. There are events that happen, so which ones should you care about?
Webhooks在大多数Stripe集成中起着至关重要的作用。 有事件发生,那么您应该关注哪些事件?
The most important webhook as a SaaS app to pay attention to is the - when a subscription goes into state cancelled. You listen for this event in order to decide what to do with someone's account when they cancel, trial runs out, or their card fails.
作为SaaS应用程序要注意的最重要的Webhook是当订阅进入取消状态时。 您侦听此事件,以便确定当某人的帐户取消,试用期结束或他们的卡失败时该如何处理。
Once you start listening to Stripe events, it is a good idea to secure your webhook receiver as not to be fed phony webhooks by a bad-actor. You do this by utilizing Stripe's webhook si gning functionality:
一旦开始收听Stripe事件,最好将Webhook接收器固定为不被不良行为者欺骗的虚假网钩。 您可以通过使用Stripe的webhook信号功能来做到这一点:
// Set your secret key: remember to change this to your live secret key in production// See your keys here: https://dashboard.stripe.com/account/apikeysconst stripe = require('stripe')('sk_test_bkoS59kZFWBR3XZgkiHwozoX00lD4ttSs1');// Find your endpoint's secret in your Dashboard's webhook settingsconst endpointSecret = 'whsec_...';// This example uses Express to receive webhooksconst app = require('express')();// Use body-parser to retrieve the raw body as a bufferconst bodyParser = require('body-parser');// Match the raw body to content type application/jsonapp.post('/webhook', bodyParser.raw({type: 'application/json'}), (request, response) => { const sig = request.headers['stripe-signature']; let event; try { event = stripe.webhooks.constructEvent(request.body, sig, endpointSecret); } catch (err) { response.status(400).send(`Webhook Error: ${err.message}`); } // Handle the event switch (event.type) { case 'payment_intent.succeeded': const paymentIntent = event.data.object; handlePaymentIntentSucceeded(paymentIntent); break; case 'payment_method.attached': const paymentMethod = event.data.object; handlePaymentMethodAttached(paymentMethod); break; // ... handle other event types default: // Unexpected event type return response.status(400).end(); } // Return a response to acknowledge receipt of the event response.json({received: true});});app.listen(8000, () => console.log('Running on port 8000'));
Your billing code can get pretty complicated when it comes to having a fully-featured solution that includes coupons, free trials, metered billing, and more.
要使用功能齐全的解决方案,包括优惠券,免费试用版,计费计费等,您的计费代码可能会变得非常复杂。
Building a user interface for your Stripe integration could take months to develop. provides a drop-in UI for Stripe Billing. It takes less than an hour to set up and doesn’t require any development effort.
为您的Stripe集成构建用户界面可能要花费数月的时间。 为Stripe Billing提供了一个 UI。 设置过程不到一个小时,不需要任何开发工作。
翻译自:
转载地址:http://oihwd.baihongyu.com/