It is showing no error but it is not reaching Firebase.
console.log(success: order ${session.id} had been added to db
); this line never comes in the console.
the terminal shows everything created but it does not reach Firebase database I am thinking there is an error in the code
The stripe dashboard also says connected
I am using the forward to localhost line in git terminal
webhook code
import { buffer } from "micro";
import * as admin from 'firebase-admin'
//secure a connection to Firebase from backend
const serviceAccount = require('../../../permissions.json');
const app = !admin.apps.length ? admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
})
: admin.app();
// establish connection to stripe
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const endpointSecret = process.env.STRIPE_SIGNING_SECRET;
if (typeof endpointSecret !== "string") {
console.error("Unexpected value for STRIPE_SIGNING_SECRET");
// potentially throw an error here
}
const fulfillOrder = async (session) => {
//console.log('Fulfilling order', session)
return app
.firestore()
.collection("user")
.doc(session.metadata.email)
.collection("orders")
.doc(session.id)
.set({
amount: session.amount_total / 100,
amount_shipping: session.amount_total_details.amount_shipping / 100,
images: JSON.parse(session.metadata.images),
timestamp: admin.firestore.FieldValue.serverTimestamp(),
})
.then(() => {
console.log(`success: order ${session.id} had been added to db`);
});
};
export default async (req, res) =>{
if(req.method === 'post'){
const requestBuffer = await buffer(req);
const payload = requestBuffer.toString();
const sig = req.headers["stripe-signature"];
let event;
// verify that the event posted came from stripe
try{
event = stripe.webhooks.constructEvent(
payload,
sig,
endpointSecret);
} catch (err) {
console.log('ERROR', err.message)
return res.status(400).send(`Webhook error: ${err.message}`)
}
//handle the checkout event
if (event.type === 'checkout.session.completed') {
const session = event .data.object;
//fulfill the order...
return fulfillOrder(session)
.then(() => res.status(200))
.catch((err) => res.status(400).send(`Webhook error: ${err.message}`));
}
}
};
export const config = {
api: {
bodyParser: false,
externalResolver: true,
},
};
firebase rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow write: if false;
allow read: if true;
}
}
}
CodePudding user response:
Trying to register default
defeats the system, which deploys individual functions:
export default async (req, res) => {
The name of the function should rather be webhook
(TypeScript example):
const functions = require("firebase-functions");
exports.webhook = functions.https.onRequest(async (request: any, response: Response) => {
Or NodeJS: https://cloud.google.com/functions/docs/calling/http#functions-calling-http-nodejs
But the problem is another: Maybe reconsider the directory structure, because there commonly are no "pages" and one doesn't need a separate file per function. These are supposed to be deployed independently, which means that trying to deploy a function from within a JS app may not work as expected. It's actually the idea of Cloud Functions, that the run on their own ...don't mix these applications (as the screenshot suggests). Better use a separate directory functions
and an independent *.js
or *.ts
file.
That webhook code may interact with Firestore, but not with the rest of that JS application.
CodePudding user response:
This code:
if (event.type === 'checkout.session.completed') {
const session = event .data.object;
//fulfill the order...
return fulfillOrder(session)
.then(() => res.status(200))
.catch((err) => res.status(400).send(`Webhook error: ${err.message}`));
}
contains two errors:
- wrong spelling (with space)
event .data.object
; - status is not sent
res.status(200)
. Probably this is the reason of errorFailed to POST: Post "http://localhost:3000/webhook": context deadline exceeded
from ypur last picture.