J'ai ajouté dans l'extension Stripe Subscriptions à mon application Firebase/Vue afin de pouvoir gérer les plans d'abonnement de mes clients, mais je rencontre des problèmes avec ce que je crois être le webhook Stripe.
J'ai commencé l'installation de l'extension en configurant le firebase.rules comme indiqué dans le tutoriel :
firebase.rules :
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write;
}
match /customers/{uid} {
allow read, write: if request.auth.uid == uid;
match /checkout_sessions/{id} {
allow read, write: if request.auth.uid == uid;
}
match /subscriptions/{id} {
allow read, write: if request.auth.uid == uid;
}
}
match /products/{id} {
allow read: if true;
allow write: if false;
match /prices/{id} {
allow read: if true;
allow write: if false;
}
}
}
}
J'ai configuré le webhook Stripe comme suit et ajouté le secret du webhook dans l'extension firebase :
J'ai également créé une clé restreinte dans le tableau de bord Stripe et je l'ai également ajoutée à l'extension.
Lorsque je teste la création d'un nouveau produit à partir du tableau de bord Stripe, le webhook réussit et une collection est créée dans firebase :
Tableau de bord des produits Stripe :
Maintenant, le problème :
Le problème survient lorsque j'essaie de créer et de compléter une caisse Stripe. D'après le tutoriel, il semble que je doive le faire en appelant stripe.redirectToCheckout()
et il s'occupera de la plupart des choses pour moi, mais je n'arrive pas à trouver le sessionId de la session de caisse. Voici l'exemple qu'ils ont montré :
const docRef = await db
.collection('customers')
.doc(currentUser.uid)
.collection('checkout_sessions')
.add({
price: 'price_1GqIC8HYgolSBA35zoTTN2Zl',
success_url: window.location.origin,
cancel_url: window.location.origin,
});
// Wait for the CheckoutSession to get attached by the extension
docRef.onSnapshot((snap) => {
const { sessionId } = snap.data();
if (sessionId) {
// We have a session, let's redirect to Checkout
// Init Stripe
const stripe = Stripe('pk_test_1234');
stripe.redirectToCheckout({ sessionId });
}
});
Voici ma mise en œuvre :
async checkoutv2(item) {
let currentUser = this.getCurrentUser();
const stripe = window.Stripe(this.publishableKey);
const docRef = await db
.firestore()
.collection("customers")
.doc(currentUser.uid)
.collection("checkout_sessions")
.add({
unit_amount: item["unit_amount"],
plan: item["id"],
description: item["description"],
interval: item["interval"],
currency: item["currency"],
type: item["type"],
interval_count: item["interval_count"],
active: item["active"],
// allow_promotion_codes: true,
// tax_rates: ["txr_1HCshzHYgolSBA35WkPjzOOi"],
success_url: window.location.origin,
cancel_url: window.location.origin,
mode: "subscription",
metadata: {},
});
// Wait for the CheckoutSession to get attached by the extension
docRef.onSnapshot((snap) => {
const { sessionId } = snap.data();
if (sessionId) {
// We have a session, let's redirect to Checkout
// Init Stripe
stripe.redirectToCheckout({ sessionId });
} else {
console.log("NOPE");
}
});
},
Il semble que le CheckOutSession "s'attache" à l'extension après qu'elle ait été ajoutée au Firestore, et qu'un ID de session soit créé et ajouté au document. Mais je ne vois pas cela se produire dans ma version. Le site checkout_sessions
sont créés, mais sans sessionId
.
Voici ce que snap
ressemble à des données :
N'a rien sur sessionId
Mais il a son propre identifiant, qui est, je crois, l'identifiant que Firestore crée automatiquement pour la collection.
En regardant mes journaux, aucun webhook n'est déclenché. Lorsque je teste des événements de webhooks spécifiques, certains réussissent et d'autres non.
Réussit :
- Tout ce qui concerne le prix, la création, la mise à jour et la suppression de produits.
- checkout.session.completed
- abonnement.client.créé
Échec (code d'état d'erreur 400) :
- abonnement.client.mis.à.jour
- customer.subscription.deleted (LOG : Le gestionnaire de Webhook pour l'événement Stripe [evt_00000000000000] de type [customer.subscription.deleted] a échoué : No such subscription : 'sub_00000000000000')
Quelqu'un peut-il dire ce qui se passe ? J'utilise la version de l'API de Stripe : 2017-06-05. J'ai ajouté ce qui suit à mon index.html
:
<!-- Firebase App (the core Firebase SDK) is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/7.14.6/firebase.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.6/firebase-functions.js"></script>
<!-- If you enabled Analytics in your project, add the Firebase SDK for Analytics -->
<script src="https://www.gstatic.com/firebasejs/7.14.5/firebase-analytics.js"></script>
<!-- Add Firebase products that you want to use -->
<script src="https://www.gstatic.com/firebasejs/7.14.5/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.5/firebase-firestore.js"></script>
<script src="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.js"></script>
<link
type="text/css"
rel="stylesheet"
href="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.css"
/>
Mon paquet.json :
{
"name": "mathpath",
"version": "0.1.0",
"private": true,
"description": "## Project setup ``` npm install ```",
"author": "",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"start": "node index.js",
"bd": "vue-cli-service build && firebase deploy"
},
"main": "babel.config.js",
"dependencies": {
"aws-sdk": "^2.719.0",
"axios": "^0.19.2",
"bootstrap": "^4.5.0",
"bootstrap-vue": "^2.1.0",
"core-js": "^3.6.5",
"dns": "^0.2.2",
"express": "^4.17.1",
"firebase": "^7.17.1",
"firebase-admin": "^9.0.0",
"firebaseui": "^4.6.0",
"fs": "0.0.1-security",
"jquery": "^3.5.1",
"katex": "^0.12.0",
"markdown-it": "^11.0.0",
"markdown-it-katex": "^2.0.3",
"mathjax-node": "^2.1.1",
"pg": "^8.2.2",
"pg-hstore": "^2.3.3",
"sequelize": "^6.3.0",
"showdown": "^1.9.1",
"showdown-katex": "^0.8.0",
"slugify": "^1.4.5",
"stripe": "^8.83.0",
"uniqid": "^5.2.0",
"vue": "^2.6.11",
"vue-katex": "^0.4.0",
"vue-router": "^3.3.4",
"vue-stripe-checkout": "^3.5.7",
"vue-youtube-embed": "^2.2.2",
"vuefire": "^2.2.3",
"vuex": "^3.5.1"
},
"devDependencies": {
"@babel/polyfill": "^7.7.0",
"@vue/cli-plugin-babel": "~4.4.0",
"@vue/cli-plugin-eslint": "~4.4.0",
"@vue/cli-service": "~4.4.0",
"babel-eslint": "^10.1.0",
"bootstrap": "^4.3.1",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"mutationobserver-shim": "^0.3.3",
"popper.js": "^1.16.0",
"portal-vue": "^2.1.6",
"sass": "^1.19.0",
"sass-loader": "^8.0.0",
"vue-cli-plugin-bootstrap-vue": "~0.6.0",
"vue-template-compiler": "^2.6.11"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {
"no-console": "off",
"no-restricted-syntax": [
"error",
{
"selector": "CallExpression[callee.object.name='console'][callee.property.name!=/^(log|warn|error|info|trace)$/]",
"message": "Unexpected property on console object was called"
}
]
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
],
"license": "ISC"
}