Skip to main content

SubscriptionMgt_SM_TSL (Codeunit)

SubscriptionMgt_SM_TSL codeunit contains all the code blocks for the integration aspect of the Subscription Management app. It comprises multiple functions as described below. Before progressing, please ensure that the Subscription Management extension is installed into your development environment and the right dependency has been defined in your extension's app.json:

dependencies
{
"id": "6717135a-d80c-4a63-8a3a-5ded6717135a",
"publisher": "Theta Systems Limited",
"name": "SubscriptionMgt",
"version": "1.0.0.0"
}

Common Parameters

NameTypeDescription
SecretKeyTextYour Stripe API Secret
This key can perform any API request to Stripe without restriction, we highly recommend you leverage a secure vault to safeguard the integrity of your account.
PublishableKeyTextYour Stripe Publishable Key
This key exists solely to identify your account with Stripe and can be considered a public identified key that can safely remain in source.
ProductIDText[100]Your Stripe Product Identifier
The identifier of the product associated with your extension.
info

SecretKey, PublishableKey and ProductID values differ across your Stripe account between your test and live modes. Use test values during development/testing and make sure you use your live key in your production-ready package. The easiest way to do this is by replacing the keyVaultUrls values within your continuous integration process.

Integration API

TryAddProduct (Method)

Requests Subscription Management to start handling your extension. It's recommended to call it with OnInstallAppPerDatabase and OnUpgradePerDatabase events.

TryAddProduct(Text;Text;ModuleInfo;Text[100]):Boolean

TryAddProduct(SecretKey,PublishableKey,Info,ProductID)
Parameters
NameTypeDescription
SecretKeyTextStripe Secret Key
PublishableKeyTextStripe Publishable Key
InfoModuleInfoIt's your extension module info object instance. It can be retrieved by using NavApp.GetCurrentModuleInfo(Info) function.
ProductIDText[100]Stripe Product ID
Returns
TypeDescription
BooleanIndicating whether the operation completed successfully
Examples
InstallExt.Codeunit.al
codeunit 50000 InstallExt
{
Subtype = Install;

trigger OnInstallAppPerDatabase()
var
SecretProvider: Codeunit "App Key Vault Secret Provider";
SubscriptionMgt: Codeunit SubscriptionMgt_SM_TSL;
Info: ModuleInfo;
[NonDebuggable]
SecretKey: Text;
[NonDebuggable]
PublishableKey: Text;
ProductID: Text[100];
begin
if NavApp.GetCurrentModuleInfo(Info) then
if SecretProvider.TryInitializeFromCurrentApp() then
if SecretProvider.GetSecret('SecretKey', SecretKey) and
SecretProvider.GetSecret('PublishableKey', PublishableKey) and
SecretProvider.GetSecret('MyAppProductID', ProductID)
then
SubscriptionMgt.TryAddProduct(
SecretKey,
PublishableKey,
Info,
ProductID);
end;
}

TryAddProduct(Text;Text;Guid;Text[100]):Boolean

TryAddProduct(SecretKey,PublishableKey,AppID,ProductID)
Parameters
NameTypeDescription
SecretKeyTextStripe Secret Key
PublishableKeyTextStripe Publishable Key
AppIDGuidThe unique ID of your extension. You can retrieve it from current module info.
ProductIDText[100]Stripe Product ID
Returns
TypeDescription
BooleanIndicating whether the operation completed successfully
Examples
InstallExt.Codeunit.al
codeunit 50000 InstallExt
{
Subtype = Install;

trigger OnInstallAppPerDatabase()
var
SecretProvider: Codeunit "App Key Vault Secret Provider";
SubscriptionMgt: Codeunit SubscriptionMgt_SM_TSL;
Info: ModuleInfo;
[NonDebuggable]
SecretKey: Text;
[NonDebuggable]
PublishableKey: Text;
ProductID: Text[100];
begin
if NavApp.GetCurrentModuleInfo(Info) then
if SecretProvider.TryInitializeFromCurrentApp() then
if SecretProvider.GetSecret('SecretKey', SecretKey) and
SecretProvider.GetSecret('PublishableKey', PublishableKey) and
SecretProvider.GetSecret('MyAppProductID', ProductID)
then
SubscriptionMgt.TryAddProduct(
SecretKey,
PublishableKey,
Info.Id(),
ProductID);
end;
}

IsActive (Method)

Checks whether the product subscription is in one of the active states (active, trialing, past_due, incomplete, incomplete_expired).

IsActive(Text;Text[100]):Boolean

IsActive(SecretKey,ProductID)
Parameters
NameTypeDescription
SecretKeyTextStripe Secret Key
ProductIDText[100]Stripe Product ID
Returns
TypeDescription
BooleanIndicates whether product subscription is in one of the active states (active, trialing, past_due, incomplete, incomplete_expired)
Examples
MyExtension.PageExt.al

pageextension 50000 MyExtension extends "Customer Card"
{
trigger OnOpenPage()
begin
CurrPage.Editable := IsActive()
end;

[NonDebuggable]
procedure IsActive(): Boolean
var
SecretProvider: Codeunit "App Key Vault Secret Provider";
SubscriptionMgt: Codeunit SubscriptionMgt_SM_TSL;
SecretKey: Text;
ProductID: Text[100];
begin
if SecretProvider.TryInitializeFromCurrentApp() then
if SecretProvider.GetSecret('SecretKey', SecretKey) and
SecretProvider.GetSecret('MyAppProductID', ProductID)
then
exit(SubscriptionMgt.IsActive(SecretKey, ProductID));
end;
}

IsTrialing (Method)

Returns whether a subscription is currently under a trial period.

IsTrialing(Text;Text[100]):Boolean

IsTrialing(SecretKey,ProductID)
Parameters
NameTypeDescription
SecretKeyTextStripe Secret Key
ProductIDText[100]Stripe Product ID
Returns
TypeDescription
BooleanIndicates whether a subscription is currently under a trial period.
Examples
MyExtension.PageExt.al
pageextension 50000 MyExtension extends "Customer Card"
{
trigger OnOpenPage()
begin
CurrPage.Editable := IsTrialing()
end;

[NonDebuggable]
procedure IsTrialing(): Boolean
var
SecretProvider: Codeunit "App Key Vault Secret Provider";
SubscriptionMgt: Codeunit SubscriptionMgt_SM_TSL;
SecretKey: Text;
ProductID: Text[100];
begin
if SecretProvider.TryInitializeFromCurrentApp() then
if SecretProvider.GetSecret('SecretKey', SecretKey) and
SecretProvider.GetSecret('MyAppProductID', ProductID)
then
exit(SubscriptionMgt.IsTrialing(SecretKey, ProductID));
end;
}

GetPriceName (Method)

Returns name of the user selected plan. Returns '' if no plan is selected.

GetPriceName(Text;Text[100]):Text

GetPriceName(SecretKey,ProductID)
Parameters
NameTypeDescription
SecretKeyTextStripe Secret Key
ProductIDText[100]Stripe Product ID
Returns
TypeDescription
TextReturns a name of a price which user selected for this product

ShowNotification (Method)

Force Subscription Management to show a notification to the user to act on the subscription. It will return false if there is nothing to show.

ShowNotification(Text;Text[100]):Boolean

ShowNotification(SecretKey,ProductID)
Parameters
NameTypeDescription
SecretKeyTextStripe Secret Key
ProductIDText[100]Stripe Product ID
Returns
TypeDescription
BooleanIndicates if any notification shows
Examples
MyExtension.PageExt.al
pageextension 50000 MyExtension extends "Customer Card"
{
trigger OnOpenPage()
begin
CurrPage.Editable := IsActive()
end;

[NonDebuggable]
procedure IsActive(): Boolean
var
SecretProvider: Codeunit "App Key Vault Secret Provider";
SubscriptionMgt: Codeunit SubscriptionMgt_SM_TSL;
SecretKey: Text;
ProductID: Text[100];
begin
if SecretProvider.TryInitializeFromCurrentApp() then
if SecretProvider.GetSecret('SecretKey', SecretKey) and
SecretProvider.GetSecret('MyAppProductID', ProductID)
then
if SubscriptionMgt.IsActive(SecretKey, ProductID) then
exit(true)
else
SubscriptionMgt.ShowNotification(SecretKey, ProductID);
end;
}

Quantity API

CountProductLines (Method)

Returns the current quantity of the specified product. Default return value is 1 if the quantity could not be found.

CountProductLines(Text;Text[100]):BigInteger

CountProductLines(SecretKey,ProductID)
Parameters
NameTypeDescription
SecretKeyTextStripe Secret Key
ProductIDText[100]Stripe Product ID
Returns
TypeDescription
BigIntegerCurrent quantity of the product

GetProductLines (Method)

Returns the list of current quantity lines.

GetProductLines(Text;Text[100];var Dictionary of [Text,JsonObject]):Boolean

GetProductLines(SecretKey,ProductID,ProductLines)
Parameters
NameTypeDescription
SecretKeyTextStripe Secret Key
ProductIDText[100]Stripe Product ID
ProductLinesDictionary of [Text, JsonObject]TBD
Returns
TypeDescription
BooleanReturns true if operation has been successful

SetProductLines (Method)

Updates the list of current quantity lines.

SetProductLines(Text;Text[100];Dictionary of [Text,JsonObject]):Boolean

SetProductLines(SecretKey,ProductID,ProductLines)
Parameters
NameTypeDescription
SecretKeyTextStripe Secret Key
ProductIDText[100]Stripe Product ID
ProductLinesDictionary of [Text, JsonObject]TBD
Returns
TypeDescription
BooleanReturns true if operation has been successful

SetProductLines(Text;Text[100];Boolean;Dictionary of [Text,JsonObject]):Boolean

SetProductLines(SecretKey,ProductID,ResetBillingCycle,ProductLines)
Parameters
NameTypeDescription
SecretKeyTextStripe Secret Key
ProductIDText[100]Stripe Product ID
ResetBillingCycleBooleanif true, it resets the subscription’s billing cycle anchor to the current time. If false, the quantity changes will be applied to a next invoice date.
ProductLinesDictionary of [Text, JsonObject]TBD
Returns
TypeDescription
BooleanReturns true if operation has been successful

SetProductLines(Text;Text[100];Dictionary of [Text,JsonObject];Boolean):Boolean

SetProductLines(SecretKey,ProductID,ProductLines,ShowConfirmation)
Parameters
NameTypeDescription
SecretKeyTextStripe Secret Key
ProductIDText[100]Stripe Product ID
ProductLinesDictionary of [Text, JsonObject]TBD
ShowConfirmationBooleanIf true, the confirmation dialog pops up with upcoming invoice information and information about what the next payment will look like and asks the user to proceed.
Returns
TypeDescription
BooleanReturns true if operation has been successful

SetProductLines(Text;Text[100];Boolean;Dictionary of [Text,JsonObject];Boolean):Boolean

SetProductLines(SecretKey,ProductID,ResetBillingCycle,ProductLines,ShowConfirmation)
Parameters
NameTypeDescription
SecretKeyTextStripe Secret Key
ProductIDText[100]Stripe Product ID
ResetBillingCycleBooleanif true, it resets the subscription’s billing cycle anchor to the current time. If false, the quantity changes will be applied to a next invoice date.
ProductLinesDictionary of [Text, JsonObject]TBD
ShowConfirmationBooleanIf true, the confirmation dialog pops up with upcoming invoice information and information about what the next payment will look like and asks the user to proceed.
Returns
TypeDescription
BooleanReturns true if operation has been successful

Mocking API

RequestMocking (Method)

Request service mocking by key provided.

RequestMocking(Text)

RequestMocking(PrivateKey)
Parameters
NameTypeDescription
PrivateKeyTextPrivate key used to authorize mocking
Examples
MyExtensionTest.Codeunit.al
codeunit 50002 "MyExtensionTest"
{
Subtype = Test;

[Test]
procedure TestMyExtension();
var
SecretProvider: Codeunit "App Key Vault Secret Provider";
SubscriptionMgt: Codeunit SubscriptionMgt_SM_TSL;
MockAuthKey: Text;
begin
// [Scenario] Check if customer card is editable when subscription is active
// [Given] my extension is installed and subscription is active
SecretProvider.TryInitializeFromCurrentApp();
SecretProvider.GetSecret('MockAuthKey', MockAuthKey);
SubscriptionMgt.RequestMocking(MockAuthKey);
SubscriptionMgt.SetMock(false, true, 'Business');
// [When] user opens a customer card
...
// [Then] customer card page is editable
...
end;
}

SetMock (Method)

Sets response which SubscriptionMgt_SM_TSL will reply during test execution.

SetMock(Boolean;Boolean;Text)

SetMock(IsTrialing,IsActive,PriceName)
Parameters
NameTypeDescription
IsTrialingBooleanDefines response for IsTrialing method
IsActiveBooleanDefines response for IsActive method
PriceNameTextDefines response for GetPriceName method
Examples
MyExtensionTest.Codeunit.al
codeunit 50002 "MyExtensionTest"
{
Subtype = Test;

[Test]
procedure TestMyExtension();
var
SecretProvider: Codeunit "App Key Vault Secret Provider";
SubscriptionMgt: Codeunit SubscriptionMgt_SM_TSL;
MockAuthKey: Text;
begin
// [Scenario] Check if customer card is editable when subscription is active
// [Given] my extension is installed and subscription is active
SecretProvider.TryInitializeFromCurrentApp();
SecretProvider.GetSecret('MockAuthKey', MockAuthKey);
SubscriptionMgt.RequestMocking(MockAuthKey);
SubscriptionMgt.SetMock(false, true, 'Business');
// [When] user opens a customer card
...
// [Then] customer card page is editable
...
end;
}

AuthorizeMocking (Method)

Allows further calls to the service to be mocked using provided private key.

AuthorizeMocking(Text)

AuthorizeMocking(PrivateKey)
Parameters
NameTypeDescription
PrivateKeyTextPrivate key used to authorize mocking
Examples
MyExtension.PageExt.al
pageextension 50000 MyExtension extends "Customer Card"
{
trigger OnOpenPage()
begin
CurrPage.Editable := IsActive()
end;

[NonDebuggable]
procedure IsActive(): Boolean
var
SecretProvider: Codeunit "App Key Vault Secret Provider";
SubscriptionMgt: Codeunit SubscriptionMgt_SM_TSL;
SecretKey: Text;
ProductID: Text[100];
MockAuthKey: Text;
begin
if SecretProvider.TryInitializeFromCurrentApp() then
if SecretProvider.GetSecret('SecretKey', SecretKey) and
SecretProvider.GetSecret('MyAppProductID', ProductID) and
SecretProvider.GetSecret('MockAuthKey', MockAuthKey)
then begin
SubscriptionMgt.AuthorizeMocking(MockAuthKey);
exit(SubscriptionMgt.IsActive(SecretKey, ProductID));
end
end;
}