peertube-plugin-sell-storage 1.1.3 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -6
- package/client/common-client-plugin.js +1 -1
- package/client/pages/subscription.js +3 -2
- package/dist/common-client-plugin.js +12 -12
- package/main.js +11 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,11 +9,13 @@
|
|
|
9
9
|
## About <a name = "about"></a>
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
This plugin
|
|
12
|
+
This plugin allows you to sell storage space to your users using Stripe subscription. Payments are automated with Stripe.
|
|
13
13
|
|
|
14
14
|
## Getting Started <a name = "getting_started"></a>
|
|
15
15
|
|
|
16
|
-
This is a fork of [peertube-plugin-ncd-sell-storage](https://gitea.nicecrew.digital/matty/peertube-plugin-ncd-sell-storage). Unfortunately, the published version on NPM is outdated and therefore does not work despite the fix being available on their Git repository. For that reason, their repository was forked and published separately with the updated code.
|
|
16
|
+
This is a fork of [peertube-plugin-ncd-sell-storage](https://gitea.nicecrew.digital/matty/peertube-plugin-ncd-sell-storage). Unfortunately, the published version on NPM is outdated **at the time of writing this** and therefore does not work despite the fix being available on their Git repository. For that reason, their repository was forked and published separately with the updated code.
|
|
17
|
+
|
|
18
|
+
Additionally, this plugin removes branding and allows users to set their own billing portal for customers.
|
|
17
19
|
|
|
18
20
|
As with [peertube-plugin-ncd-sell-storage](https://gitea.nicecrew.digital/matty/peertube-plugin-ncd-sell-storage), this fork allows you to add five packages rather than three.
|
|
19
21
|
|
|
@@ -48,14 +50,23 @@ To go in live mode, you need to fill form in Stripe side. We recommand you to te
|
|
|
48
50
|
### Note: If you perform a transaction in Test Mode, you'll need to manually clear the subscription status because the webhook will not send back the correct validation response, meaning the changes will take effect but nothing will be charged. Use a dedicated test account.
|
|
49
51
|
|
|
50
52
|
First, go to the Developer tab, and navigate to "API Keys". Grab your Secret API key, and insert it in your plugin settings.
|
|
51
|
-
|
|
53
|
+
|
|
54
|
+
After that, always in the Developer tab, navigate to Webhook and create a webhook with the following API events:
|
|
55
|
+
- `checkout.session.completed`
|
|
56
|
+
- `customer.subscription.created`
|
|
57
|
+
- `customer.subscription.deleted`
|
|
58
|
+
- `customer.subscription.trial_will_end`
|
|
59
|
+
- `customer.subscription.updated`
|
|
60
|
+
- `invoice.paid`
|
|
61
|
+
- `invoice.payment_failed`
|
|
62
|
+
- `payment_intent.succeeded`
|
|
52
63
|
|
|
53
64
|
An example of webhook URL is available in your plugin settings. An example is also shown here:
|
|
54
65
|
https://your-instance.tld/plugins/sell-storage/1.1.3/router/webhook
|
|
55
66
|
|
|
56
67
|
### Note: If you update the plugin, you'll have to update the webhook link in Stripe with the new version. For example, update 1.1.3 to 1.1.4. Don't forget this!
|
|
57
68
|
|
|
58
|
-
Now, configure your
|
|
69
|
+
Now, configure your billing portal, currency, page and description in the plugin settings.
|
|
59
70
|
|
|
60
71
|
Its time to add your Plans! In stripe, go to Product page, and add new product. Set a name, description and the price.
|
|
61
72
|
After creation, go in this new Product and grab the "API ID" near the price field.
|
|
@@ -65,5 +76,4 @@ Repeat this process for each plans. Add new product, and grab the API ID corresp
|
|
|
65
76
|
|
|
66
77
|
## Usage <a name = "usage"></a>
|
|
67
78
|
|
|
68
|
-
- Navigate to "My
|
|
69
|
-
- Navigate to the new navigation link "My Subscription"
|
|
79
|
+
- Navigate to "Storage Plan" underneath "My video space" in the PeerTube menu
|
|
@@ -8,6 +8,7 @@ async function showPage({ rootEl, peertubeHelpers }) {
|
|
|
8
8
|
|
|
9
9
|
// Get settings
|
|
10
10
|
const settings = await peertubeHelpers.getSettings();
|
|
11
|
+
const billingPortal = settings["stripe-billing-portal"];
|
|
11
12
|
const currency = settings['sell-currency'];
|
|
12
13
|
const description = await peertubeHelpers.markdownRenderer.enhancedMarkdownToHTML(settings["sell-description"]);
|
|
13
14
|
const plans = [];
|
|
@@ -83,7 +84,7 @@ async function showPage({ rootEl, peertubeHelpers }) {
|
|
|
83
84
|
<p><i><b>${await translate("Your current plan")}</b>: ${sub_plan.name}, ${currency}${sub_plan.price} /${await peertubeHelpers.translate("month")}, ${sub_plan.storage} ${await peertubeHelpers.translate("GB Storage")}</i></p>
|
|
84
85
|
|
|
85
86
|
<div>
|
|
86
|
-
<a href="
|
|
87
|
+
<a href="${billingPortal}" target="_blank" style="font-size: 1.25rem; background-color: #0083f5; color: white; border-radius: 0.25rem; padding: 0.5rem 0.75rem; margin-top: 1.25rem;">Manage Subcription</a>
|
|
87
88
|
<div>
|
|
88
89
|
` : ""}
|
|
89
90
|
|
|
@@ -158,4 +159,4 @@ function listenSubmitSubscription(peertubeHelpers) {
|
|
|
158
159
|
});
|
|
159
160
|
}
|
|
160
161
|
|
|
161
|
-
export { showPage };
|
|
162
|
+
export { showPage };
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
var h=Object.defineProperty;var
|
|
1
|
+
var h=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var F=Object.prototype.hasOwnProperty;var u=(n,t)=>()=>(n&&(t=n(n=0)),t);var l=(n,t)=>{for(var a in t)h(n,a,{get:t[a],enumerable:!0})},p=(n,t,a,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of x(t))!F.call(n,i)&&i!==a&&h(n,i,{get:()=>t[i],enumerable:!(s=A(t,i))||s.enumerable});return n};var g=n=>p(h({},"__esModule",{value:!0}),n);var b={};l(b,{showPage:()=>B});async function B({rootEl:n,peertubeHelpers:t}){var S,v;if(!t.isLoggedIn())return window.location.href="/login";let{translate:a}=t,s=await t.translate("Loading");n.innerHTML=s+"...";let i=await t.getSettings(),o=i["stripe-billing-portal"],r=i["sell-currency"],f=await t.markdownRenderer.enhancedMarkdownToHTML(i["sell-description"]),w=[];for(let c=1;c<=5;c++){let M=i["plan-"+c+"-name"],U=i["plan-"+c+"-key"],R=i["plan-"+c+"-storage"],_=i["plan-"+c+"-price"];w.push({name:M,key:U,storage:R,price:_})}let m=null,d=null,e=await(await fetch(t.getBaseRouterRoute()+"/get-session-id",{method:"GET",headers:t.getAuthHeader()})).json();!e||!e.status||e.status&&e.status!=="success"?t.notifier.error(e.message||"Unknown error"):(m=(S=e==null?void 0:e.data)==null?void 0:S.session_id,d=(v=e==null?void 0:e.data)==null?void 0:v.sub_plan),n.innerHTML=`
|
|
2
2
|
<div class="ncd-content text-center">
|
|
3
3
|
<h1>${await t.translate("Choose your Storage Plan")}</h1>
|
|
4
4
|
<h5><i>To subscribe to a storage plan with cryptocurrency (BTC, ETH, XMR), <a href="/about/contact">contact us</a>.</i></h5>
|
|
5
5
|
<h6><i>Note: Cryptocurrency prices are 25% higher to cover transaction fees.</i></h6>
|
|
6
|
-
<!-- <p>${
|
|
6
|
+
<!-- <p>${f.length?f:await t.translate("You want tu spport us ? Or need more space ? Your in the right place!")}</p> -->
|
|
7
7
|
<div class="mt-5" style="max-width: 90%; margin: 0 auto;">
|
|
8
8
|
<div class="row">
|
|
9
|
-
${(await Promise.all(
|
|
9
|
+
${(await Promise.all(w.map(async c=>`<div class="col-sm-12 col-md-6 col-lg-4" style="margin-bottom: 1rem;">
|
|
10
10
|
<div class="card">
|
|
11
11
|
<div class="card-body">
|
|
12
12
|
<form method="POST" action="#" class="ncdSubscriptionForm">
|
|
13
13
|
<h3 class="card-title">${c.name}</h3>
|
|
14
|
-
<h4>${
|
|
14
|
+
<h4>${r}${c.price} /${await t.translate("month")}</h4>
|
|
15
15
|
<p class="card-text">${c.storage} ${await t.translate("GB Storage")}</p>
|
|
16
16
|
|
|
17
17
|
<input type="hidden" name="lookup_key" value="${c.key}">
|
|
@@ -35,30 +35,30 @@ var h=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var A=Object.g
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
${d?`
|
|
38
|
-
<p><i><b>${await a("Your current plan")}</b>: ${d.name}, ${
|
|
38
|
+
<p><i><b>${await a("Your current plan")}</b>: ${d.name}, ${r}${d.price} /${await t.translate("month")}, ${d.storage} ${await t.translate("GB Storage")}</i></p>
|
|
39
39
|
|
|
40
40
|
<div>
|
|
41
|
-
<a href="
|
|
41
|
+
<a href="${o}" target="_blank" style="font-size: 1.25rem; background-color: #0083f5; color: white; border-radius: 0.25rem; padding: 0.5rem 0.75rem; margin-top: 1.25rem;">Manage Subcription</a>
|
|
42
42
|
<div>
|
|
43
43
|
`:""}
|
|
44
44
|
|
|
45
45
|
</div>
|
|
46
|
-
`;let
|
|
46
|
+
`;let y=()=>{document.querySelectorAll(".ncdSubscriptionForm").length===5?D(t):setTimeout(()=>y(),1e3)};y()}function D(n){var a;let t=n.getBaseRouterRoute();document.querySelectorAll(".ncdSubscriptionForm").forEach(s=>{s.addEventListener("submit",i=>{i.preventDefault();try{let o=new URLSearchParams(new FormData(i.target));fetch(t+"/create-checkout-session",{method:"POST",headers:n.getAuthHeader(),body:o}).then(r=>r.json()).then(r=>{if(!r||!r.status||r.status!=="success"){n.notifier.error(r.message||"Unknown error");return}window.location.href=r.data.redirectUrl}).catch(r=>{console.error(r),n.notifier.error(r)})}catch(o){n.notifier.error(o)}})}),(a=document.getElementById("formManageSub"))==null||a.addEventListener("submit",s=>{s.preventDefault();try{let i=new URLSearchParams(new FormData(s.target));fetch(t+"/create-portal-session",{method:"POST",headers:n.getAuthHeader(),body:i}).then(o=>o.json()).then(o=>{if(!o||!o.status||o.status!=="success"){n.notifier.error(o.message||"Unknown error");return}window.location.href=o.data.redirectUrl}).catch(o=>{console.error(o),n.notifier.error(o)})}catch(i){n.notifier.error(i)}})}var $=u(()=>{});var k={};l(k,{showPage:()=>O});async function O({rootEl:n,peertubeHelpers:t}){if(!t.isLoggedIn())return window.location.href="/login";let a=await t.translate("Loading");n.innerHTML=a+"...";let{translate:s}=t,i=await t.markdownRenderer.enhancedMarkdownToHTML(settings["sell-thx-description"]);n.innerHTML=`
|
|
47
47
|
<div class="ncd-content text-center mt-5">
|
|
48
48
|
<h1>${await t.translate("Subscription succesfull!")}</h1>
|
|
49
49
|
|
|
50
50
|
<div class="mt-5">
|
|
51
51
|
<form action="#" method="POST" class="ncdSubscriptionForm">
|
|
52
52
|
<input type="hidden" id="session-id" name="session_id" value="" />
|
|
53
|
-
<button id="checkout-and-portal-button" type="submit" class="btn btn-primary">${await
|
|
53
|
+
<button id="checkout-and-portal-button" type="submit" class="btn btn-primary">${await s("Manage my Subscription")}</button>
|
|
54
54
|
</form>
|
|
55
55
|
</div>
|
|
56
56
|
|
|
57
|
-
<p>${
|
|
57
|
+
<p>${i}</p>
|
|
58
58
|
</div>
|
|
59
|
-
`,setTimeout(()=>
|
|
59
|
+
`,setTimeout(()=>j(t),1e3)}function j(n){let t=n.getBaseRouterRoute(),a=new URLSearchParams(window.location.search);if(a.has("session_id")){document.getElementById("session-id").value=a.get("session_id"),localStorage.setItem("ncd-sub-session-id",a.get("session_id"));let s=new FormData;s.append("session_id",a.get("session_id"));let i=new URLSearchParams(s);fetch(t+"/save-session-id",{method:"POST",headers:n.getAuthHeader(),body:i}).then(o=>o.json()).then(o=>{(!o||!o.status||o.status!=="success")&&n.notifier.error(o.message||"Unknown error")}).catch(o=>{console.error(o),n.notifier.error(o)})}document.querySelector(".ncdSubscriptionForm").addEventListener("submit",s=>{s.preventDefault();try{let i=new URLSearchParams(new FormData(s.target));fetch(t+"/create-portal-session",{method:"POST",headers:n.getAuthHeader(),body:i}).then(o=>o.json()).then(o=>{if(!o||!o.status||o.status!=="success"){n.notifier.error(o.message||"Unknown error");return}window.location.href=o.data.redirectUrl}).catch(o=>{console.error(o),n.notifier.error(o)})}catch(i){n.notifier.error(i)}})}var L=u(()=>{});var P={};l(P,{showPage:()=>q});async function q({rootEl:n,peertubeHelpers:t}){if(!t.isLoggedIn())return window.location.href="/login";let a=await t.getSettings(),s=await t.markdownRenderer.enhancedMarkdownToHTML(a["sell-cancel-description"]);n.innerHTML=`
|
|
60
60
|
<div class="ncd-content text-center mt-5">
|
|
61
61
|
<h1>${await t.translate("Subscription canceled.")}</h1>
|
|
62
|
-
<p>${
|
|
62
|
+
<p>${s}</p>
|
|
63
63
|
</div>
|
|
64
|
-
`}var T=u(()=>{});var
|
|
64
|
+
`}var T=u(()=>{});var E=($(),g(b)),I=(L(),g(k)),G=(T(),g(P));async function C({registerHook:n,peertubeHelpers:t,registerClientRoute:a}){n({target:"filter:left-menu.links.create.result",handler:s=>{if(!Array.isArray(s))return s;let i;for(let r of s)if(typeof r=="object"&&"key"in r&&(r.key==="in-my-library"||r.key==="my-video-space")){i=r;break}if(!i||!Array.isArray(i.links))return s;let o="Storage Plan";return i.links.unshift({label:o,shortLabel:o,path:"/p/ncd-my-subscription",icon:"film"}),s}}),a({route:"ncd-my-subscription",onMount:({rootEl:s})=>{E.showPage({rootEl:s,peertubeHelpers:t})}}),a({route:"ncd-subscription-success",onMount:({rootEl:s})=>{I.showPage({rootEl:s,peertubeHelpers:t})}}),a({route:"ncd-subscription-cancel",onMount:({rootEl:s})=>{G.showPage({rootEl:s,peertubeHelpers:t})}})}export{C as register};
|
package/main.js
CHANGED
|
@@ -371,9 +371,18 @@ function registerMenuSettings(registerSetting) {
|
|
|
371
371
|
default: ""
|
|
372
372
|
});
|
|
373
373
|
|
|
374
|
+
registerSetting({
|
|
375
|
+
name: "stripe-billing-portal",
|
|
376
|
+
label: "Stripe Billing Portal",
|
|
377
|
+
type: "input",
|
|
378
|
+
private: false,
|
|
379
|
+
descriptionHTML:" "The Stripe billing portal where customers can manage their subscriptions. Enabled at: https://dashboard.stripe.com/settings/billing/portal",
|
|
380
|
+
default: ""
|
|
381
|
+
});
|
|
382
|
+
|
|
374
383
|
registerSetting({
|
|
375
384
|
type: 'html',
|
|
376
|
-
html: '<h4>Stripe Webhook</h4><p>You need to create a webhook in stripe. Set the stripe webhook endpoint to <b>https://your-instance.tld/plugins/
|
|
385
|
+
html: '<h4>Stripe Webhook</h4><p>You need to create a webhook in stripe. Set the stripe webhook endpoint to <b>https://your-instance.tld/plugins/sell-storage/'+pjson.version+'/router/webhook</b></p>'
|
|
377
386
|
})
|
|
378
387
|
|
|
379
388
|
registerSetting({
|
|
@@ -625,4 +634,4 @@ function registerMenuSettings(registerSetting) {
|
|
|
625
634
|
descriptionHTML: "Specify the product ID that represent the product in Stripe (Ex: price_1LlHY6KHtJzgTzXzZTBRHkPs)",
|
|
626
635
|
default: "profesionnal",
|
|
627
636
|
});
|
|
628
|
-
}
|
|
637
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "peertube-plugin-sell-storage",
|
|
3
3
|
"description": "Updated and republished version of peertube-plugin-ncd-sell-storage to sell storage to users using Stripe",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.4",
|
|
5
5
|
"author": "AyaaDev",
|
|
6
6
|
"bugs": "https://github.com/ayaadev/peertube-plugin-sell-storage",
|
|
7
7
|
"clientScripts": [
|