npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

tamed-stripe-backend

v1.1.13

Published

The backend library for the tamed-stripe

Downloads

18

Readme

WHY?

This is the backend library for the Tamed Stripe architecture. This library aims to provide the backend integrations with the Stripe API servers for basic customer generation, connected account generation, subscription generation and payment functions.

SETUP

  1. Add the backend library to the backend of your project.
yarn add tamed-stripe-backend
  1. Modify the TAMED_STRIPE_SECRET_KEY environment parameter to use to connect to the Stripe.
export TAMED_STRIPE_SECRET_KEY="YOUR_STRIPE_SECRET_KEY" # starts with sk_
  1. Initialize parameters (modify below object according to your environment)

    Use this file as a template for your backend configuration. This file is to be required by your express server in the next step. You should modify the credentials, according to your environment.

    | Key | Type | Value | | --- | --- | --- | | pgKeys | Object | PostgreSQL connection parameters. | | debugMode | Boolean | If true, the library will log debug messages. |

  2. Call the init function of the library to initialize the db connection pool. And then start your server. As a reference you can use this file which utilize the tamed-express-server library for a quick start.

API

init

The init function initializes the database connection pool. Additionally it provides a method to increase the log level.

| Parameter | Type | Description | | --- | --- | --- | | p_params | Object | Parameters for the backend server. |

p_params

| Key | Type | Value | | --- | --- | --- | | pgKeys | Object | PostgreSQL connection parameters. | | debugMode | Boolean | If true, the library will log debug messages. |

Returns

If successful, resolves to true. Otherwise, rejects with an error message.

Example

const tsb = require("../tamed-stripe-backend.js");
...
await tsb.init({
	debugMode: debugMode,
	// coming from database-setup
	pgKeys: {
		user: 'tamedstripeapp',
		password: 'tamedstripeapp.',
		database: 'tamedstripedb',
		host: 'localhost',
		port: 5432,
	},
});

generateCustomer

Generates a payer customer at Stripe and attaches a payment method to it so that the customer can do payments.

Reading Data from Database

Once a customer is generated, you can reach the customer within your database from the tamedstripe.customers table. The application_customer_id field of the tamedstripe.customers table is the applicationCustomerId parameter of this function. You can use this field to link your application's customer structure with the Stripe side customer id.

| Parameter | Type | Description | | --- | --- | --- | | body | Object | Parameters for the generating a payer customer at Stripe |

body

| Key | Type | Value | | --- | --- | --- | | applicationCustomerId | string | This is your application's customer id that you can use to link your application customer structure with stripe side customer id. | | paymentMethodId(optional) | string | Payment method id of the payment method to be attached to the customer. If this is omitted a new payment method will be generated with a checkout session. | | description | string | Description of the customer. | | email | string | Email of the customer. | | metadata | Object | Metadata for the customer, you can embed andy data within this object, it is kept in Stripe servers also. | | name | string | Name of the customer. | | phone | string | Phone number of the customer. | | address | Object | Address of the customer. | | publicDomain | string | Public domain of the website. | | successRoute | string | Route to redirect to on successful checkout. Defaults to /generate-customer-success-route which is handled by the library function generateCustomerSuccessRoute. We suggest you to keep this as undefined and use the default value because the default value signals frontend a method to close WebViews. | | cancelRoute | string | Route to redirect to on cancelled checkout. Defaults to /generate-customer-cancel-route which is handled by the library function generateCustomerCancelRoute. We suggest you to keep this as undefined and use the default value because the default value signals frontend a method to close WebViews. | | testClockId(optional) | string | This is an optional clock id that is a method that Stripe provides for future dated tests. For an example usage, you can refer to subscriptionPayment - next 2 months tests. |

address

| Key | Type | Value | | --- | --- | --- | | city | string | City of the customer. | | country | string | Country of the customer. | | line1 | string | Line 1 of the address of the customer. | | line2 | string | Line 2 of the address of the customer. | | postal_code | string | Postal code of the customer. | | state | string | State of the customer. |

Returns

If successful, resolves to below JSON object. The checkoutSession object is optional and it holds the checkout session information which can be used to collect the default payment method information from users. Otherwise, rejects with an error message.

{
	result: 'OK',
	payload: {
		customer,
		checkoutSession
	},
}

Example

   ...
	const body = { applicationCustomerId, description, email, metadata, name, phone, address, publicDomain };
	let response = await tsb.generateCustomer(body);

generateCustomerSuccessRoute

This is the default route handler for the generateCustomer handler. This is used if the successRoute parameter of the generateCustomer handler is a falsy value. We suggest you to use this handler because the redirect signals frontend a method to close WebViews.

generateCustomerCancelRoute

This is the default route handler for the generateCustomer handler. This is used if the cancelRoute parameter of the generateCustomer handler is a falsy value. We suggest you to use this handler because the redirect signals frontend a method to close WebViews, and it also unlinks a customer so that it can not provide hurdles for future operations.

getCustomer

Gets stripe customer information from the database, using the applicationCustomerId parameter.

| Parameter | Type | Description | | --- | --- | --- | | body | Object | Parameters for the generating a payer customer at Stripe |

body

| Key | Type | Value | | --- | --- | --- | | applicationCustomerId | string | This is your application's customer id that you can use to link your application customer structure with stripe side customer id. |

Returns

If successful, resolves to below JSON object. Otherwise, rejects with an error message.

{
	result: 'OK',
	payload: {
		customer // customer.rows[0] from DB with selected columns
	},
}

Example

   ...
	const body = { applicationCustomerId };
	let response = await tsb.getCustomer(body);

generateProduct

Generates a product that can be used in checkout sessions that is to be a basis for subscriptions. Once a product is generated, you can reach the product within your database from the tamedstripe.products table. The stripe_product_id field of the tamedstripe.products table is the Stripe's product id.

| Parameter | Type | Description | | --- | --- | --- | | body | Object | Parameters for the generating a payer customer at Stripe |

body

| Key | Type | Value | | --- | --- | --- | | name | string | Name of the product. | | description | string | Description of the product. | | currency | string | Currency of the product. | | unitAmountDecimal | number | Unit amount of the product in CENTS. | | interval | string | Interval of the product. This can be one of following values; 'day', 'week', 'month', 'year'. | | taxBehavior | string | Optional. Tax behavior of the product. This can be one of following values; 'exclusive', 'inclusive', 'unspecified'. | | taxCode | string | Optional. Tax code of the product. Comes from the Stripe's Product Tax Categories. |

Returns

If successful, resolves to below JSON object. Otherwise, rejects with an error message.

{
	result: 'OK',
	payload: {
		product,
		price
	},
}

Example

	const body = {
		name: 'Test Product',
		description: 'Test Product Description',
		currency: 'usd',
		unitAmountDecimal: 1000, // This value is in cents, so it is $10.00, 
		interval: 'month',
		taxBehavior: 'exclusive',
		taxCode: 'txcd_30060006' // Stripe tax code for hats. :-) 
	};
	let response = await tsb.generateProduct(body);

generateSubscription

Generates a subscription for a customer. Once a subscription is generated, you can reach the subscription within your database from the tamedstripe.subscriptions table. The stripe_subscription_id field of the tamedstripe.subscriptions table is the Stripe's subscription id. The stripe_product_id field of the tamedstripe.subscriptions table is the Stripe's product id. The state field can be one of following values; 'A' (active), 'C'(cancelled). As long as a subscription is active the Stripe will charge the customer automatically.

Reading Data from Database

Once Stripe charges a customer for a subscription, it is received via a 'invoice.paid' web hook. And when that webhook indicating a successfull payment is made, tamedstripe.subscription_payments table is modified accordingly. In this table you can check if current date-time is between the subscription_covered_from and subscription_covered_to fields of any row of the same subscription's payments. If it is, then the subscription is covered for that period. If it is not, then the subscription is not covered for that period. You can use this information to determine if a subscription is covered for a period or not and serve your functionality to your customer.

For example below row from the tamedstripe.subscription_payments table indicates that the subscription is covered for the period between 2023-03-23 14:36:36 and 2023-04-23 14:36:36. So if you want to check if a subscription is covered for the current date-time, you can check if the current date-time is between 2023-03-23 14:36:36 and 2023-04-23 14:36:36. If it is, then the subscription is covered for that period. If it is not, then the subscription is not covered for that period.

 id |    stripe_subscription_id    | unit_amount_decimal | currency | state | subscription_covered_from | subscription_covered_to 
----+------------------------------+---------------------+----------+-------+---------------------------+-------------------------
  1 | sub_1MopFoCDKfcpGwAfZiZTD1Gg |              100001 | usd      | P     | 2023-03-23 14:36:36       | 2023-04-23 14:36:36

| Parameter | Type | Description | | --- | --- | --- | | body | Object | Parameters for the generating a subscription at Stripe |

body

| Key | Type | Value | | --- | --- | --- | | customerId | string | Stripe customer id that the subscription will be generated for. | | recurringPriceId | string | Stripe price id of the recurring price, which should be previously generated using generateProduct function. | | description | string | Description of the subscription. | | automaticTax | object | Optional. Automatic tax settings of the subscription. If to be used following object should be passed: { enabled: true } | | unlinkIfSubscriptionFails | boolean | Optional. If set to true, then the customer will be unlinked from the application if the subscription fails. |

Returns

If successful, resolves to below JSON object. Otherwise, rejects with an error message.

{
	result: 'OK',
	payload: subscription,
}

Example

const productProps = {
	name: 'Test',
	description: 'Test',
	currency: 'usd',
	unitAmountDecimal: '1234567', // This value is in cents, so it is $12345,67,
	interval: 'month',
	taxBehavior: 'exclusive',
	taxCode: 'txcd_30060006' // Stripe tax code for hats. :-)
};
const response2 = await tsb.generateProduct(productProps);
const priceData = response2.payload.price;
...
await tsb.generateSubscription({
	applicationCustomerId: applicationCustomerId,
	recurringPriceId: priceData.id,
	description: description,
	automaticTax: { enabled: true },
	unlinkIfSubscriptionFails: true,
});

getSubscriptionPayments

Gets the payments of an application customer id for all subscriptions. The retrieved list can be filtered to find the needed payments.

| Parameter | Type | Description | | --- | --- | --- | | body | Object | Parameters for the generating a payer customer at Stripe |

body

| Key | Type | Value | | --- | --- | --- | | applicationCustomerId | string | Application customer id of the customer that the subscription payments will be retrieved for. |

Returns

If successful, resolves to below JSON object. Otherwise, rejects with an error message.

{
	result: 'OK',
	payload: subscriptionPayments,
}

Example

const response = await tsb.getSubscriptionPayments({
	applicationCustomerId: applicationCustomerId,
});

cancelSubscription

Cancels a subscription.

| Parameter | Type | Description | | --- | --- | --- | | body | Object | Parameters for the generating a payer customer at Stripe |

body

| Key | Type | Value | | --- | --- | --- | | subscriptionId | string | Id of the subscription to be cancelled. |

Returns

If successful, resolves to below JSON object where subscription object is coming from Stripe. Otherwise, rejects with an error message.

{
	result: 'OK',
	payload: subscription,
}

Example

	const body = {
		subscriptionId: 'sub_1234567890',
	};
	let response = await tsb.cancelSubscription(body);

generateAccount

Generates a payee account (aka connected account) at Stripe and its associated account link for the end user to complete the account generation process on Stripe.

The account link is generated for the end user to complete the account generation process on Stripe. The end user should be redirected to the Stripe's website to complete the account generation process using the returned link. After the account generation process is completed, the end user will be redirected to the return URL of the account link.

Reading Data from Database

The connected account information for a customer is kept in the tamedstripe.connected_accounts table. In this table application_customer_id is the customer id of your system and it is to be used to link your software to the generated application_customer_id. The state field can be either 'W' or A. W means the account is waiting for the end user to complete the account generation process on Stripe. 'A' means the account is active and ready to be used. For 'W' rows, you can re-call this function to recieeve an active URL that you can use to direct your users to complete their account generation process on Stripe.

| Parameter | Type | Description | | --- | --- | --- | | body | Object | Parameters for the generating a payee account at Stripe |

body

| Key | Type | Value | | --- | --- | --- | | applicationCustomerId | string | Id of the application customer that the account will be generated for. | | email | string | Email of the account. | | publicDomain | String | Public domain of the server, to use the return URLs. | | refreshUrlRoute | String | Route for the refresh URL. Defaults to /generate-account-cancel-route for which the route can be handled by this library.| | returnUrlRoute | String | Route for the return URL. Defaults to /generate-account-success-route for which the route can be handled by this library.| | country | String | Country of the account. Defaults to US. | | capabilities | JSON | Defaults to {transfers: { requested: true }} |

Returns

You should expect 3 different responses from this function.

  • If there is a successfully generated account for the given applicationCustomerId, then the response will be as below, and the payload.id can be used as Stripe side payee (connected_account) id.
{
	result: 'OK',
	payload: {
		id: result.rows[0].stripe_account_id,
		accountLinkURL: ''
	}
}
  • If previously account generation process started but the end user did not complete the process, then the response will be as below, and the payload.accountLinkURL can be used to redirect the end user to the Stripe's website to complete the account generation process. Use the accountLinkURL field to redirect the end user to the Stripe's website to complete the account generation process.
{
	result: 'OK',
	payload: {
		id: result.rows[0].stripe_account_id,
		accountLinkURL: accountLinkForW.url,
		urlRegenerated: true
	}
}
  • If there is no account for the given applicationCustomerId, then the response will be as below, and the payload.accountLinkURL can be used to redirect the end user to the Stripe's website to start the account generation process.
{
	result: 'OK',
	payload: {
		result: 'OK',
		payload: account,
	}
}

Example

const props = {
	applicationCustomerId,
	email,
	publicDomain,
	country,
};
const response1 = await tsb.generateAccount(props);

generateAccountSuccessRoute

Provides the default route content for th /generate-account-success-route route. This route is used to handle the return URL of the account link. The default route content can be used as is, or you can use it as a template to create your own route content.

generateAccountCancelRoute

Provides the default route content for th /generate-account-cancel-route route. This route is used to handle the refresh URL of the account link. The default route content can be used as is, or you can use it as a template to create your own route content.

getAccount

Gets the account information for the given applicationCustomerId.

| Parameter | Type | Description | | --- | --- | --- | | body | Object | Parameters for the generating a payee account at Stripe |

body

| Key | Type | Value | | --- | --- | --- | | applicationCustomerId | string | Id of the application customer that the account will be generated for. |

Returns

If successful, resolves to below JSON object. Otherwise, rejects with an error message.

{
	result: 'OK',
	payload: account, // account.rows[0] from DB with selected columns
}

Example

	const response2 = await tsb.getAccount({applicationCustomerId});

oneTimePayment

Generates a one time payment checkout session at Stripe. You can use that session URL to direct your users to the Stripe's website to complete the payment process.

Reading Data from Database

The payment data is kept in the tamedstripe.one_time_payments table. In this table application_customer_id is the customer id of your system and it is to be used to link your software to the generated checkout_session_id. The state field can be either 'W', 'P' or F. W means the payment is waiting for the end user to complete the payment process on Stripe. 'P' means the payment is completed. 'F' means payment is failed.

Additionally, for successfully paid customers, if you need to show your customer the related invoice, you can call the url residing in the hosted_invoice_url field.

| Parameter | Type | Description | | --- | --- | --- | | body | Object | Parameters for the generating a one time payment checkout session at Stripe |

body

| Key | Type | Value | | --- | --- | --- | | applicationCustomerId | string | Id of the application customer that the payment will be generated for. | | currency | string | Currency of the payment. | | items | Array | Array of items to be paid. | | payoutData | Object | Payout data for the payment. | | publicDomain | String | Public domain of the server, to use the return URLs. | | automaticTax | Object | (Optional) Automatic tax data for the payment. If sent, should be the object: { enabled: true } | | newCustomerParams | Object | (Optional) This is only for oneTimePayment scenarios where no persistent customer exists, like the subscription or saved payment method scenarios. If sent, a new customer will be generated with the given parameters if there is no existing customer with the applicationCustomerId parameter. |

items

| Key | Type | Value | | --- | --- | --- | | name | string | Name of the item. | | amount | string | Amount of the item, in cents. | | tax_code | string | Tax code of the item. Comes from the Stripe's Product Tax Categories. |

payoutData

| Key | Type | Value | | --- | --- | --- | | payoutAmount | string | Amount to be paid to the payee, in cents. | | payoutAccountId | string | Stripe account id of the payee. |

newCustomerParams

| Key | Type | Value | | --- | --- | --- | | email | string | Email of the customer. | | description | string | Description of the customer. | | metadata | Object | Metadata for the customer, you can embed andy data within this object, it is kept in Stripe servers also. | | name | string | Name of the customer. | | phone | string | Phone number of the customer. | | address | Object | Address of the customer. |

Returns

Returns the checkoutSession object created by Stripe. The url field of the returned payload can be used to redirect the end user to the Stripe's website to complete the payment process.

{
	result: 'OK',
	payload: checkoutSession,
}

Example

const currency = 'eur';
const items = [
	// txcd_30060006 is the tax code for the "Hats" category in https://stripe.com/docs/tax/tax-categories
	{ name: "Red Hat", unitAmountDecimal: "100000", tax_code: 'txcd_30060006' }, 
	{ name: "Green Hat", unitAmountDecimal: "200000", tax_code: 'txcd_30060006' },
	{ name: "Blue Hat", unitAmountDecimal: "300000", tax_code: 'txcd_30060006' },
];
const payoutData = {
	payoutAmount: "225000",
	payoutAccountId: "some-account-id-who-will-receive-the-payment",
	useOnBehalfOf: true
};
const automaticTax = { enabled: true };
const props = {
	applicationCustomerId,
	currency,
	items,
	payoutData,
	publicDomain,
	automaticTax,
};
const response3 = await tsb.oneTimePayment(props);

oneTimePaymentSuccessRoute

Provides the default route content for th /one-time-payment-success-route route. This route is used to handle the return URL of the checkout session. The default route content can be used as is, or you can use it as a template to create your own route content. We suggest to use this route because it helps to manage the frontend application web view state.

oneTimePaymentCancelRoute

Provides the default route content for th /one-time-payment-cancel-route route. This route is used to handle the refresh URL of the checkout session. The default route content can be used as is, or you can use it as a template to create your own route content. We suggest to use this route because it helps to manage the frontend application web view state.

getOneTimePaymentStatus

Returns the status of a one time payment.

| Parameter | Type | Description | | --- | --- | --- | | body | Object | Parameters for the generating a one time payment checkout session at Stripe |

body

| Key | Type | Value | | --- | --- | --- | | checkoutSessionId | string | Id of the checkout session. |

Returns

The payload holds the database state of the requested payment.

{
	result: 'OK',
	payload: rows,
}

The payload.rows[0] is a database row in the following form:

 id |              application_customer_id               | stripe_customer_id |                        checkout_session_id                         |        update_time         | total_amount_decimal | currency | state |         invoice_id          |                                                                      hosted_invoice_url                                                                       | payout_amount |   payout_account_id   | payout_state 
----+----------------------------------------------------+--------------------+--------------------------------------------------------------------+----------------------------+----------------------+----------+-------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+-----------------------+--------------
  2 | Application Customer-1679582193973                 | cus_... | cs_xxxx... | 2023-03-24 14:34:57.000013 |               450000 | eur      | P     | in_... | https://invoice.stripe.com/i/acct_.../test_...?s=ap |        225000 | acct_... | W

Here the state = 'P' means the payment is completed. And you can ues the url in the hosted_invoice_url field to show the invoice to the customer.

refundOneTimePayment

Refunds a completed one time payment using the checkout session id.

| Parameter | Type | Description | | --- | --- | --- | | body | Object | The object that holds the parmeters |

body

| Key | Type | Value | | --- | --- | --- | | checkoutSessionId | string | Id of the checkout session. |

Returns

The payload holds the refund object coming from Stripe.

{
	result: 'OK',
	payload: refund,
}

Example

const checkoutSessionIdToRefund = "cs_XXX"; // completed checkout session id of the payment to be refunded
await tsb.refundOneTimePayment({ checkoutSessionId: checkoutSessionIdToRefund });

webhook

This is a webhook endpoint that can be used to handle the Stripe events. The events are directed to different functions.

This library handles following events

| Event | Function | Description | | --- | --- | --- | | checkout.session.completed | webhookCheckoutSessionCompletedSetup or webhookCheckoutSessionCompletedPayment | Stripe sends this event when a checkout session for a new customer payment method is completed or when a one time payment is done. This library checks the event.data.object.mode parameter to differentiate these 2 events. | | invoice.paid | webhookSubscriptionInvoicePaid | We use this event to detect subscription payments. For this purpose we check if the event.data.object.billing_reason field is subscription related or not. (If it is not subscription related, it is ignored.) | | account.updated | webhookAccountUpdated | We use this event to detect connected account updates. And we check the event.data.object.charges_enabled and the event.data.object.payouts_enabled parameters to decide if the connected account is successfully generated or not. |

Using the data in the DB

The tamed-stripe libraries provide the fundamental functionalities connecting to the Stripe. However, if there is no change at Stripe, the data in the database can be used to get latest state of the customers, connected accounts, subscriptions and payments without calling Stripe.

For these purposes we suggest to familiarize yourself with the database structure. The ERD of the database can be found below.

ERD

More Examples

The example application can be found here. Also the jest test cases can be used as examples, which can be found here.

License

The license is MIT and full text here.

Used Modules

Please refer to the main github page for the list of used modules.