diff --git a/Plugins/BTCPayServer.Plugins.Subscriptions/BTCPayServer.Plugins.Subscriptions.csproj b/Plugins/BTCPayServer.Plugins.Subscriptions/BTCPayServer.Plugins.Subscriptions.csproj
index 38640b4..8157c3f 100644
--- a/Plugins/BTCPayServer.Plugins.Subscriptions/BTCPayServer.Plugins.Subscriptions.csproj
+++ b/Plugins/BTCPayServer.Plugins.Subscriptions/BTCPayServer.Plugins.Subscriptions.csproj
@@ -10,7 +10,7 @@
Subscriptions
Offer and manage subscriptions through BTCPay Server
- 1.0.0
+ 1.0.1
true
diff --git a/Plugins/BTCPayServer.Plugins.Subscriptions/GreenfieldSubscriptionsController.cs b/Plugins/BTCPayServer.Plugins.Subscriptions/GreenfieldSubscriptionsController.cs
index 2efe4e4..e99d472 100644
--- a/Plugins/BTCPayServer.Plugins.Subscriptions/GreenfieldSubscriptionsController.cs
+++ b/Plugins/BTCPayServer.Plugins.Subscriptions/GreenfieldSubscriptionsController.cs
@@ -33,6 +33,23 @@ public class GreenfieldSubscriptionsController : ControllerBase
var ss = app.GetSettings();
return Ok(ss);
+ }
+ [HttpGet("~/api/v1/apps/subscriptions/{appId}/{subscriptionId}")]
+ [AllowAnonymous]
+ public async Task GetSubscriptionId(string appId, string subscriptionId)
+ {
+ var app = await _appService.GetApp(appId, SubscriptionApp.AppType, includeArchived: true);
+ if (app == null)
+ {
+ return AppNotFound();
+ }
+
+ var ss = app.GetSettings();
+ if (!ss.Subscriptions.TryGetValue(subscriptionId, out var subscriber))
+ {
+ return this.CreateAPIError(404, "subscription-not-found", "The subscription with specified ID was not found");
+ }
+ return Ok(subscriber);
}
private IActionResult AppNotFound()
diff --git a/Plugins/BTCPayServer.Plugins.Subscriptions/Resources/swagger.subscriptions.json b/Plugins/BTCPayServer.Plugins.Subscriptions/Resources/swagger.subscriptions.json
new file mode 100644
index 0000000..cc6e95e
--- /dev/null
+++ b/Plugins/BTCPayServer.Plugins.Subscriptions/Resources/swagger.subscriptions.json
@@ -0,0 +1,230 @@
+{
+ "paths": {
+ "/api/v1/apps/subscriptions/{appId}": {
+ "parameters": [
+ {
+ "name": "appId",
+ "in": "path",
+ "required": true,
+ "description": "The ID of the subscription app",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "get": {
+ "operationId": "Subscriptions_GetSubscriptionApp",
+ "summary": "Get a subscription app and all of its details",
+ "responses": {
+ "200": {
+ "description": "Subscription details",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/SubscriptionAppSettings"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The subscription was not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Subscriptions"
+ ],
+ "security": [
+ {
+ "API_Key": [
+ "btcpay.store.canmodifystoresettings"
+ ],
+ "Basic": []
+ }
+ ]
+ }
+ },
+ "/api/v1/apps/subscriptions/{appId}/{subscriptionId}": {
+ "parameters": [
+ {
+ "name": "appId",
+ "in": "path",
+ "required": true,
+ "description": "The ID of the subscription app",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "subscriptionId",
+ "in": "path",
+ "required": true,
+ "description": "The ID of the subscription",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "get": {
+ "operationId": "Subscriptions_GetSubscriptionOfApp",
+ "summary": "Get a subscription of a subscription app",
+ "responses": {
+ "200": {
+ "description": "Subscription details",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Subscription"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "The subscription was not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "Subscriptions (Public)"
+ ],
+ "security": [ ]
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+
+ "SubscriptionDurationType": {
+ "type": "string",
+ "description": "",
+ "x-enumNames": [
+ "Day",
+ "Month"
+ ],
+ "enum": [
+ "Day",
+ "Month"
+ ]
+ },
+ "SubscriptionStatus": {
+ "type": "string",
+ "description": "",
+ "x-enumNames": [
+ "Active",
+ "Inactive"
+ ],
+ "enum": [
+ "Active",
+ "Inactive"
+ ]
+ },
+
+ "SubscriptionPayment": {
+ "type": "object",
+ "properties": {
+ "paymentRequestId": {
+ "type": "string",
+ "description": "The payment request Id that handles this payment."
+ },
+
+ "periodStart": {
+ "description": "What period starts with this payment",
+ "allOf": [ { "$ref": "#/components/schemas/UnixTimestamp" } ]
+ },
+ "periodEnd": {
+ "description": "What period ends with this payment",
+ "allOf": [ { "$ref": "#/components/schemas/UnixTimestamp" } ]
+ },
+ "settled": {
+ "type": "boolean",
+ "description": "Whether the payment has been settled"
+ }
+ }
+ },
+ "Subscription": {
+ "type": "object",
+ "properties": {
+ "email": {
+ "type": "string",
+ "description": "Email of the subscription user"
+ },
+ "status": {
+ "$ref": "#/components/schemas/SubscriptionStatus"
+ },
+ "start": {
+ "description": "When the subscription was first activated",
+ "allOf": [ { "$ref": "#/components/schemas/UnixTimestamp" } ]
+ },
+ "payments": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/SubscriptionPayment"
+ }
+ }
+ }
+ },"SubscriptionSet": {
+ "type": "object",
+ "additionalProperties": {
+
+ "$ref": "#/components/schemas/Subscription"
+ }
+ },
+ "SubscriptionAppSettings": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "description": {
+ "type": "string",
+ "description": "Description of the subscription app"
+ },
+ "duration": {
+ "type": "number",
+ "description": "Duration of the subscription (type of duration is defined in the `durationType` field)"
+ },
+ "durationType": {
+ "$ref": "#/components/schemas/SubscriptionDurationType"
+ },
+ "formId": {
+ "type": "string",
+ "description": "Form ID to request customer data",
+ "nullable": true
+ },
+ "price": {
+ "type": "string",
+ "description": "The price of the subscription"
+ },
+ "currency": {
+ "type": "string",
+ "description": "The currency of the subscription"
+ },
+ "subscriptions": {
+ "$ref": "#/components/schemas/SubscriptionSet"
+ }
+ }
+
+
+ }
+ },
+ "tags": [
+ {
+ "name": "Subscriptions",
+ "description": "Subscriptions operations"
+ } , {
+ "name": "Subscriptions (Public)",
+ "description": "Subscriptions public endpoints"
+ }
+ ]
+ }
+}
diff --git a/Plugins/BTCPayServer.Plugins.Subscriptions/SubscriptionPlugin.cs b/Plugins/BTCPayServer.Plugins.Subscriptions/SubscriptionPlugin.cs
index 6074a54..ac3ce82 100644
--- a/Plugins/BTCPayServer.Plugins.Subscriptions/SubscriptionPlugin.cs
+++ b/Plugins/BTCPayServer.Plugins.Subscriptions/SubscriptionPlugin.cs
@@ -1,10 +1,16 @@
+using System.IO;
+using System.Threading.Tasks;
using BTCPayServer.Abstractions.Contracts;
using BTCPayServer.Abstractions.Extensions;
using BTCPayServer.Abstractions.Models;
using BTCPayServer.Abstractions.Services;
using BTCPayServer.HostedServices.Webhooks;
+using BTCPayServer.Services;
using BTCPayServer.Services.Apps;
+using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.FileProviders;
+using Newtonsoft.Json.Linq;
namespace BTCPayServer.Plugins.Subscriptions
{
@@ -17,6 +23,8 @@ namespace BTCPayServer.Plugins.Subscriptions
public override void Execute(IServiceCollection applicationBuilder)
{
+
+ applicationBuilder.AddSingleton();
applicationBuilder.AddSingleton();
applicationBuilder.AddSingleton(o => o.GetRequiredService());
applicationBuilder.AddHostedService(s => s.GetRequiredService());
@@ -26,4 +34,23 @@ namespace BTCPayServer.Plugins.Subscriptions
base.Execute(applicationBuilder);
}
}
+
+ public class SubscriptionsSwaggerProvider: ISwaggerProvider
+ {
+ private readonly IFileProvider _fileProvider;
+
+ public SubscriptionsSwaggerProvider(IWebHostEnvironment webHostEnvironment)
+ {
+
+ _fileProvider = webHostEnvironment.WebRootFileProvider;
+ }
+
+ public async Task Fetch()
+ {
+
+ var file = _fileProvider.GetFileInfo("Resources/swagger.subscriptions.json");
+ using var reader = new StreamReader(file.CreateReadStream());
+ return JObject.Parse(await reader.ReadToEndAsync());
+ }
+ }
}
\ No newline at end of file