Learn how to Integrate Stripe Payments API Using Google Apps Script.
The Stripe Payment Links Generator creates one-time payment links that can be shared with customers. It was originally developed by Amit Argarwal, whom I credit for this work. His version of the automation consists of using Google Apps Script to call the Stripe Payments API to generate a payment link for a single item. He also implements a cache system to enhance performance.
Expanding on his script, I introduced 3 new features:
- Multiple Item Payment Links: Users can specify up to 20 items they wish to sell, allowing them to include several items in one payment link.
- Post-Payment Actions: Following a successful payment, users can opt to redirect customers to a designated URL or display a custom message.
- Receipt and Post-Purchase Invoice: Stripe automatically sends a receipt and post-purchase invoice to the customer’s email upon completing a payment.
Please ensure proper configuration of the Stripe API when using this script.
/**
* How to Integrate Stripe Payments API Using Google Apps Script
*
* Written with ❤️ by Joseph Asinyo
*/
// Insert the API key you created on your Stripe dashboard
const STRIPE_API_KEY = "INSERT STRIPE API KEY HERE TO START";
/**
* Generate a Stripe payment link for multiple items using Google Sheets
*
* @param {Array} items An array of arrays, where each sub-array contains the item name and the amount to be charged
* @param {string} currency The 3-letter currency code for the items
* @param {string} actionAfterPayment This is either an https URL to redirect the buyer to after payment or a text message to display after payment
* @return {string} Stripe payment link
* @customfunction
*/
function STRIPE(items, currency, actionAfterPayment) {
return createLink(items, currency, actionAfterPayment);
}
function createLink(items, currency, actionAfterPayment) {
const lineItems = items.map((item, index) => {
const priceId = getPriceId(item[0], Math.ceil(item[1] * 100), currency);
return {
[`line_items[${index}][price]`]: priceId,
[`line_items[${index}][quantity]`]: 1
};
});
var key = `link${JSON.stringify(items)}${actionAfterPayment}`;
if(key.length < 100){
var paymentLink = getCache(key);
if (paymentLink) return paymentLink;
}
if(isURL(actionAfterPayment)){
var response = postData('https://api.stripe.com/v1/payment_links', {
...Object.assign({}, ...lineItems),
'after_completion[type]': 'redirect',
'after_completion[redirect][url]': actionAfterPayment,
'invoice_creation[enabled]': true,
});
} else if(actionAfterPayment != "") {
var response = postData('https://api.stripe.com/v1/payment_links', {
...Object.assign({}, ...lineItems),
'after_completion[type]': 'hosted_confirmation',
'after_completion[hosted_confirmation][custom_message]': actionAfterPayment,
'invoice_creation[enabled]': true,
});
}
const url = response.url;
if(key.length < 100){
setCache(key, url);
}
return url;
}
function getPriceId(name, price = '1234', currency = 'USD') {
const product_id = getProductId(name);
const key = product_id + price + currency;
const priceId = getCache(key);
if (priceId) return priceId;
const api = 'https://api.stripe.com/v1/prices';
const { data = [] } = getData(api, { limit: 100, currency, product: product_id });
const { id: newPriceId } =
data.find(({ unit_amount }) => String(unit_amount) === String(price)) ||
postData(api, { currency, product: product_id, unit_amount: price });
setCache(key, newPriceId);
return newPriceId;
}
function getProductId(name) {
const productId = getCache(name);
if (productId) return productId;
const api = 'https://api.stripe.com/v1/products';
const { data = [] } = getData(api, { limit: 100 });
const { id: newProductId } =
data.find(({ name: productName }) => productName === name) || postData(api, { name });
setCache(name, newProductId);
return newProductId;
}
function getData(endpoint, params) {
const response = UrlFetchApp.fetch(`${endpoint}?${convertPayload(params)}`, {
headers: {
Authorization: `Bearer ${STRIPE_API_KEY}`,
},
});
return JSON.parse(response);
}
function postData(endpoint, params) {
const response = UrlFetchApp.fetch(endpoint, {
method: 'POST',
headers: {
Authorization: `Bearer ${STRIPE_API_KEY}`,
'Content-Type': 'application/x-www-form-urlencoded',
},
payload: convertPayload(params),
});
return JSON.parse(response);
}
function convertPayload(params = {}) {
return Object.entries(params)
.map(([key, value]) => [encodeURIComponent(key), encodeURIComponent(value)].join('='))
.join('&');
}
function isURL(str) {
var httpsRegex = /^https:\/\//;
return httpsRegex.test(str);
}
function getCache(key) {
return CacheService.getScriptCache().get(key);
}
function setCache(key, value) {
CacheService.getScriptCache().put(key, value, 21600);
}
It’s possible to extend this script to generate subscription payment links for recurring charges to customers.