PLEASE help us help you by writing a good post!
Site : camping-arolla-2018.netlify.app
Dev branch : https://function-stripe-v2--camping-arolla-2018.netlify.app/shop/
-
I followed the (brillant one, thnaks) tutorial you made to integrate Stripe with Netlify.
-
All works fine, and after adapting some design things, I have a working site (dev) made with Hugo and Netlify Functions. Perfect. I can order what I want. Cool.
-
But I was dev on Chrome/Brave.
-
When I try to test with safari, all if fine, except that I get an error when the
https://function-stripe-v2--camping-arolla-2018.netlify.app/.netlify/functions/create-checkout
is called. -
The error is an error 502 witch is a “bad proxy” error. So it seems on the Netlify side.
This is the detailed error in have in Safari dev tools. Again all works fine with Chrome.
I’m trying to debug this thing for hours. Starting to getting nuts
Any idea ? Found nothing similar on the forum.
Header is:
Résumé
URL: https://function-stripe-v2--camping-arolla-2018.netlify.app/.netlify/functions/create-checkout
État: 502
Source: RĂ©seau
Adresse: 167.99.137.12:443
Initiateur:
stripe-purchase.js:11
Demande
:method: POST
:scheme: https
:authority: function-stripe-v2--camping-arolla-2018.netlify.app
:path: /.netlify/functions/create-checkout
Cookie: __stripe_mid=78d3cca6-1bd8-49ac-b139-85c0c8bda2240ee215; __stripe_sid=44010473-fa4a-4d67-8cf6-6cbfe1cdd868e0c689; displayCookieConsent=y
Accept: */*
Content-Type: application/json
Origin: https://function-stripe-v2--camping-arolla-2018.netlify.app
Accept-Encoding: br, gzip, deflate
Host: function-stripe-v2--camping-arolla-2018.netlify.app
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15
Content-Length: 33
Accept-Language: fr-fr
Connection: keep-alive
RĂ©ponse
:status: 502
Content-Type: text/plain; charset=utf-8
Age: 1
Date: Tue, 01 Sep 2020 12:13:34 GMT
Content-Length: 621
Cache-Control: no-cache
Server: Netlify
x-nf-request-id: 991cff8b-b98c-4440-ac2c-c0b7b6c29d13-28898704
Données de la demande
Type MIME: application/json
Données de la demande: {"sku":"CARTE-01","quantity":"1"}
Response is :
"errorType": "Error",
"errorMessage": "Invalid URL: undefined/undefined/thanks/. URLs must begin with http or https.",
"trace": [
"Error: Invalid URL: undefined/undefined/thanks/. URLs must begin with http or https.",
" at Function.generate (/var/task/src/node_modules/stripe/lib/Error.js:39:16)",
" at IncomingMessage.<anonymous> (/var/task/src/node_modules/stripe/lib/StripeResource.js:190:33)",
" at Object.onceWrapper (events.js:421:28)",
" at IncomingMessage.emit (events.js:327:22)",
" at endReadableNT (_stream_readable.js:1221:12)",
" at processTicksAndRejections (internal/process/task_queues.js:84:21)"
]
}
My 2 scripts are:
/functions/create-checkout.js
// Stripe secret Key on Netlify ENV Variable
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
// The inventory (Only one language at the moment)
const inventory = require('./data/products.json');
exports.handler = async (event) => {
// get the mandatory information for charging the client : sku + quantity
// The following URLs are set according to form language
// Get language (formlang) transmited from the form
// Get Absolute path for images on the Stripe checkout page
const { sku, quantity, formlang, stripeImgPath, stripeImg } = JSON.parse(event.body);
// Find the product
const product = inventory.find((p) => p.sku === sku);
// Sanitize quantity
const validateQuantity = quantity > 0 && quantity < 11 ? quantity : 1;
function root(formlang) {
let rootUrl;
if (formlang == "fr") {
rootUrl = ``;
} else {
rootUrl = `/`+formlang;
}
return rootUrl;
}
// Get the return URL part for the used language
const rootUrl = root(formlang);
// Create Stripe session
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
billing_address_collection: 'auto',
shipping_address_collection: {
// All available countries Worldwide
allowed_countries: ['AC','AD','AE','AF','AG','AI','AL','AM','AO','AQ','AR','AT','AU','AW','AX','AZ','BA','BB','BD','BE','BF','BG','BH','BI','BJ','BL','BM','BN','BO','BQ','BR','BS','BT','BV','BW','BY','BZ','CA','CD','CF','CG','CH','CI','CK','CL','CM','CN','CO','CR','CV','CW','CY','CZ','DE','DJ','DK','DM','DO','DZ','EC','EE','EG','EH','ER','ES','ET','FI','FJ','FK','FO','FR','GA','GB','GD','GE','GF','GG','GH','GI','GL','GM','GN','GP','GQ','GR','GS','GT','GU','GW','GY','HK','HN','HR','HT','HU','ID','IE','IL','IM','IN','IO','IQ','IS','IT','JE','JM','JO','JP','KE','KG','KH','KI','KM','KN','KR','KW','KY','KZ','LA','LB','LC','LI','LK','LR','LS','LT','LU','LV','LY','MA','MC','MD','ME','MF','MG','MK','ML','MM','MN','MO','MQ','MR','MS','MT','MU','MV','MW','MX','MY','MZ','NA','NC','NE','NG','NI','NL','NO','NP','NR','NU','NZ','OM','PA','PE','PF','PG','PH','PK','PL','PM','PN','PR','PS','PT','PY','QA','RE','RO','RS','RU','RW','SA','SB','SC','SE','SG','SH','SI','SJ','SK','SL','SM','SN','SO','SR','SS','ST','SV','SX','SZ','TA','TC','TD','TF','TG','TH','TJ','TK','TL','TM','TN','TO','TR','TT','TV','TW','TZ','UA','UG','US','UY','UZ','VA','VC','VE','VG','VN','VU','WF','WS','XK','YE','YT','ZA','ZM','ZW','ZZ']
},
// The real next URL for the web site language
success_url: stripeImgPath+rootUrl+`/thanks/`,
cancel_url: stripeImgPath+rootUrl+`/oops/`,
// Informations about the product
line_items: [
{
name: `[`+product.sku+'] '+product.name ,
description: product.description,
images: [stripeImg],
amount: product.amount,
currency: product.currency,
quantity: validateQuantity,
},
],
});
return {
statusCode: 200,
body: JSON.stringify({
sessionId: session.id,
publishableKey: process.env.STRIPE_PUBLISHABLE_KEY,
}),
};
};
/js/stripe-purchase.js
// Handle form the Submit button
export async function handleFormSubmission(event) {
event.preventDefault();
// Custom Goal for plausible.io
plausible('ShopOrderClick');
const form = new FormData(event.target);
// Get the mandatory data from the form
// formlang : for multilanguage sites
// stripeImgPath : for local images in STATIC
// stripeImg : for local images in ASSETS
const data = {
sku: form.get('sku'),
quantity: form.get('quantity'),
formlang: form.get('formlang'),
stripeImgPath: form.get(`stripeImgPath`),
stripeImg: form.get(`stripeImg`),
};
// Create a Stripe Checkout
const response = await fetch ('/.netlify/functions/create-checkout', {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify(data),
}).then((res) => res.json());
// Manage Checkout response & SessionID
const stripe = Stripe(response.publishableKey);
const { error } = await stripe.redirectToCheckout({
sessionId: response.sessionId,
});
if (error) {
console.error(error);
}
}