Subscriptions

A recurring payment arrangement for products or services

πŸ‘

How do Subscriptions work

Securely.io simplifies the subscription process.

A Merchant can create a subscription (subscription invitation), on behalf of a Customer who then receives a notification to accept that invitation. Subscription invitations that are not accepted prior to the start date will automatically be cancelled.

When a customer accepts the subscription invite, a Payment Request will be generated on the recurrence pattern that is provided when the subscription is created and automatically paid with the pre-selected payment method the customer sets up when the invite is accepted through the Securely.io Customer Portal.

By accepting the subscription invitation, customers opt-in to this seamless payment process, eliminating the need for manual intervention in future billing cycles.

πŸ” Create a Subscription

Securely.io empowers merchants to effortlessly create and manage subscriptions for their customers.

Choose from various billing frequencies, including weekly, every other week, bi-monthly (1st and 15th), monthly, quarterly, or annually.

For added flexibility, attach a unique external identifier, include detailed notes, or set a specific end date for the subscription.

With Securely.io streamlined API, all of this can be accomplished in a single, simple call.

securelyApiKey="YOUR_SECURELY_API_KEY"
securelyApiSecret="YOUR_SECURELY_API_SECRET"
authorization=$(echo -n "$securelyApiKey:$securelyApiSecret" | base64)

curl -X POST \
  --location 'https://sandbox-api.securelyme.io/subscriptions/create' \
  -H "Authorization: Basic $authorization" \
  -H "Content-Type: application/json" \
--data '{
  "memo": "Memo: subscription",
  "customerMessage": "Customer Message: This is a Weekly subscription",
  "customerUserId": "SECURELY_CUSTOMER_ID",
  "amount": 15.00,
  "attachment": {
    "name": "AdditionalInfo",
    "content": "a little additional text goes here",
    "mimeType": "text/plain"
  },
  "frequency": "WEEKLY",
  "endDate": "2024-12-31",
  "effectiveDate": "2024-10-01",
  "sendPaymentReminders": true
}'
var apiKey = "YOUR_API_KEY";
var apiSecret = "YOUR_API_SECRET";
var encodedCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{apiKey}:{apiSecret}"));

var jsonData = @"
{
  ""memo"": ""Memo: subscription"",
  ""customerMessage"": ""Customer Message: This is a Weekly subscription"",
  ""customerUserId"": {{customer_securelyId}},
  ""amount"": 15.00,
  ""frequency"": ""WEEKLY"",
  ""endDate"": ""2024-12-31"",
  ""effectiveDate"": ""2024-10-01"",
  ""sendPaymentReminders"": true
}
";

var client = new HttpClient();
var request = new HttpRequestMessage(
  HttpMethod.Post, 
  "https://sandbox-api.securelyme.io/subscriptions/create");
request.Headers.Add("Authorization", $"Basic {encodedCredentials}");
var content = new StringContent(jsonData, null, "application/json");

request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());

const axios = require('axios');
const apiKey = "YOUR_API_KEY";
const apiSecret = "YOUR_API_SECRET";
const encodedCredentials = Buffer.from(`${apiKey}:${apiSecret}`).toString('base64');

let data = JSON.stringify({
  "memo": "Memo: subscription",
  "customerMessage": "Customer Message: This is a Weekly subscription",
  "customerUserId": SECURELY_CUSTOMER_ID,
  "amount": 15.00,
  "frequency": "WEEKLY",
  "endDate": "2024-12-31",
  "effectiveDate": "2024-10-01",
  "sendPaymentReminders": true
});

let config = {
  method: 'post',
  maxBodyLength: Infinity,
  url: 'https://sandbox-api.securelyme.io/subscriptions/create',
  headers: { 
    'Content-Type': 'application/json', 
    'Authorization': `Basic ${encodedCredentials}`
  },
  data : data
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});

Securely.io returns a subscriptionId after the subscription is created successfully. Retain this subscriptionId as it is necessary to perform further operations on the subscription.

Subscription frequency may be: WEEKLY, EVERY OTHER WEEK, BIMONTHLY(1st and 15th), MONTHLY, QUARTERLY, YEARLY.

API reference: Create and send a subscription.

The response of a successful call, looks like this:

{
    "payload": {
        "subscriptionId": 123456
    },
    "success": true
}

πŸ“˜

Customer Approval

A Merchant could register a subscription with Securely.io, but that subscription is not active until the Customer approves the subscription.

Therefore, it is imperative that the customer logon to the Securely.io portal and approve the subscription.

If a subscription has not been accepted before the subscription start date, Securely.io automatically expires the subscription. The Webhook is notified of this event.


🎬 Operations on a Subscription

Securely.io empowers merchants with granular control over their subscriptions. Merchants can seamlessly cancel, suspend, resume, or update subscriptions, ensuring they can effectively manage their transactions and cater to evolving customer needs.

Given below is an example of invoking the suspend Subscription API and the cancel and resume endpoints are similar.

securelyApiKey="YOUR_SECURELY_API_KEY"
securelyApiSecret="YOUR_SECURELY_API_SECRET"
authorization=$(echo -n "$securelyApiKey:$securelyApiSecret" | base64)
subscriptionId=1

curl --location --request PUT \
	'https://sandbox-api.securelyme.io/subscriptions/{subscriptionId}/suspend' \
	-H "Authorization: Basic $authorization"
var apiKey = "YOUR_API_KEY";
var apiSecret = "YOUR_API_SECRET";
var encodedCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{apiKey}:{apiSecret}"));
var subscriptionId = 1

var client = new HttpClient();
var request = new HttpRequestMessage(
  HttpMethod.Put, 
  $"https://sandbox-api.securelyme.io/subscriptions/{subscriptionId}/suspend");
request.Headers.Add("Authorization", $"Basic {encodedCredentials}");

var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());

const axios = require('axios');
const apiKey = "YOUR_API_KEY";
const apiSecret = "YOUR_API_SECRET";
const encodedCredentials = Buffer.from(`${apiKey}:${apiSecret}`).toString('base64');
const subscriptionId = 1

let config = {
  method: 'put',
  url: 'https://sandbox-api.securelyme.io/subscriptions/{subscriptionId}/suspend',
  headers: { 
    'Authorization': `Basic ${encodedCredentials}`
  }
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});

Operations are visible on the Merchant Portal:

API reference: Suspend a subscription., Resume a subscription., Cancel a subscription.

Subscriptions: Scheduled and Invites for a Customer

Subscriptions: Scheduled and Invites for a Customer


πŸ”Ž Searching for Subscriptions

Securely.io allows Merchants to find their Subscriptions transactions and retrieve all of the data used to create the transaction. This endpoint offers many ways to search for transactions. The search properties must be precise and Securely.io does not allow for wild card searches and not all search properties are mandatory for the request.

In order to derive a list of transactions, use the createdFromDate and createdToDate properties for a specific customerId (a securely provided customer identifier).

securelyApiKey="YOUR_SECURELY_API_KEY"
securelyApiSecret="YOUR_SECURELY_API_SECRET"
authorization=$(echo -n "$securelyApiKey:$securelyApiSecret" | base64)
customerId=1

curl -X POST
--location 'https://sandbox-api.securelyme.io/subscriptions/search' \
-H 'Content-Type: application/json' \
-H "Authorization: Basic $authorization" \
-H "Acceptes: application/json" \
--data '{
  "createdFromDate": "2024-01-01",
  "createdToDate": "2024-12-31",
  "customerId": ${customerId},
  "pageSize": 20,
  "page": 1
}'
var apiKey = "YOUR_API_KEY";
var apiSecret = "YOUR_API_SECRET";
var encodedCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{apiKey}:{apiSecret}"));

var jsonData = @"
{
  ""createdFromDate"": ""2024-01-01"",
  ""createdToDate"": ""2024-12-31"",
  ""customerId"": 1,
  ""pageSize"": 20,
  ""page"": 1
}
";
var client = new HttpClient();
var request = new HttpRequestMessage(
  HttpMethod.Post, 
  "https://sandbox-api.securelyme.io/subscriptions/search");
request.Headers.Add("Authorization", $"Basic {encodedCredentials}");
var content = new StringContent(jsonData, null, "application/json");

request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());

const axios = require('axios');
const apiKey = "YOUR_API_KEY";
const apiSecret = "YOUR_API_SECRET";
const encodedCredentials = Buffer.from(`${apiKey}:${apiSecret}`).toString('base64');
const subscriptionId = 1

let data = JSON.stringify({
  "createdFromDate": "2024-01-01",
  "createdToDate": "2024-12-31",
  "customerId": 1,
  "pageSize": 20,
  "page": 1
});

let config = {
  method: 'post',
  maxBodyLength: Infinity,
  url: 'https://sandbox-api.securelyme.io/subscriptions/search',
  headers: { 
    'Content-Type': 'application/json', 
    'Authorization': `Basic ${encodedCredentials}`
  },
  data : data
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});

API reference: Search subscriptions requests.


🏦 Subscription Payment Requests

Securely.io simplifies recurring payments for both merchants and customers. When a customer accepts a subscription, automatic payment requests are generated at the designated intervals. This ensures a smooth payment process without requiring customer intervention.

Merchants can easily access detailed information about subscriptions and their associated transactions (payment requests) through Securely.io user-friendly API. This transparency allows for efficient management and tracking of recurring revenue streams.

const axios = require('axios');

securelyApiKey="YOUR_SECURELY_API_KEY"
securelyApiSecret="YOUR_SECURELY_API_SECRET"
authorization=$(echo -n "$securelyApiKey:$securelyApiSecret" | base64)
customerId=1

let config = {
  method: 'get',
  maxBodyLength: Infinity,
  url: 'https://sandbox-api.securelyme.io/subscriptions/$subscriptionId/payment-requests?pageSize=20&pageNumber=1',
  headers: { 
    'Authorization': 'Basic $authorization'
  }
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});

var apiKey = "YOUR_API_KEY";
var apiSecret = "YOUR_API_SECRET";
var encodedCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{apiKey}:{apiSecret}"));
var customerId = 1;

var client = new HttpClient();
var request = new HttpRequestMessage(
  HttpMethod.Get, 
  $"https://sandbox-api.securelyme.io/subscriptions/{customerId}/payment-requests?pageSize=20&pageNumber=1");
request.Headers.Add("Authorization", $"Basic {encodedCredentials}");

var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());

const axios = require('axios');

const apiKey = "YOUR_API_KEY";
const apiSecret = "YOUR_API_SECRET";
const encodedCredentials = Buffer.from(`${apiKey}:${apiSecret}`).toString('base64');
const customerId = 1

let config = {
  method: 'get',
  url: `https://sandbox-api.securelyme.io/subscriptions/${customerId}/payment-requests?pageSize=20&pageNumber=1`,
  headers: { 
    'Authorization': `Basic ${encodedCredentials}`
  }
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});

A successful response to this call will look like this:

{
    "hasMore": false,
    "totalCount": 1,
    "payload": [
        {
            "paymentRequestId": 123,
            "statusCode": "PAID",
            "amount": 0.01,
            "tipAmount": 0.00,
            "totalAmount": 0.01,
            "message": "Customer Message: This is a Weekly subscription",
            "createdDate": "2024-01-01T00:00:00.00000+00:00",
            "completedDate": "2024-01-01T00:00:00.00000+00:00"
        }
    ],
    "success": true
}

πŸ“Ž Attachments to Subscriptions

Merchants may find it useful to attach a document to a subscription, possibly, the terms of the subscription. Securely.io allows adding attachments to Subscriptions.

When creating a subscription, simply leverage the attachments property. This property takes two pieces of information: a base64 encoded string representing your document and the corresponding MIME type (e.g., "application/pdf"). Secure.io will securely store this attachment and make it readily available when you need to access details about the subscription, ensuring both security and easy access for your subscribers.

const axios = require('axios');

securelyApiKey="YOUR_SECURELY_API_KEY"
securelyApiSecret="YOUR_SECURELY_API_SECRET"
authorization=$(echo -n "$securelyApiKey:$securelyApiSecret" | base64)

curl --location 'https://sandbox-api.securelyme.io/subscriptions/create' \
-H 'Content-Type: application/json' \
-H 'Authorization': 'Basic $authorization' \
--data '{
    "memo": "Memo",
    "customerMessage": "Message for the customer",
    "customerUserId": 1111,
    "internalNotes": "Internal notes for the Merchants reference",
    "invoiceNumber": "INVOICE-NUMBER-001",
    "amount": 0.01,
      "attachment": {
        "name": "Agreement",
        "content": "dGhpcyBpcyBhIHRlc3QgZmlsZSBvbmx5Lgo=",
        "mimeType": "text/plain"
      },
    "frequency": "Weekly",
    "endDate": "2025-01-01",
    "effectiveDate": "2025-01-01",
    "paymentTermValue": 12,
    "externalIdentifier": "INV-123"
}'
var apiKey = "YOUR_API_KEY";
var apiSecret = "YOUR_API_SECRET";
var encodedCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{apiKey}:{apiSecret}"));

string json = @"{
    ""memo"": ""Memo"",
    ""customerMessage"": ""Message for customer"",
    ""customerUserId"": 1111,
    ""internalNotes"": ""Internal notes for Merchants reference"",
    ""invoiceNumber"": ""INVOICE-NO-001"",
    ""amount"": 0.01,
    ""attachment"": {
        ""name"": ""Agreement"",
        ""content"": ""dGhpcyBpcyBhIHRlc3QgZmlsZSBvbmx5Lgo="",
        ""mimeType"": ""text/plain""
    },
    ""frequency"": ""Weekly"",
    ""endDate"": ""2025-01-01"",
    ""effectiveDate"": ""2025-01-01"",
    ""paymentTermValue"": 12,
    ""externalIdentifier"": ""INV-123""
}";

var client = new HttpClient();
var request = new HttpRequestMessage(
  HttpMethod.Post, 
  "https://sandbox-api.securelyme.io/subscriptions/create");
request.Headers.Add("Authorization", $"Basic {encodedCredentials}");
request.Content = new StringContent(json, null, "application/json");

var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());

const axios = require('axios');

const apiKey = "YOUR_API_KEY";
const apiSecret = "YOUR_API_SECRET";
const encodedCredentials = Buffer.from(`${apiKey}:${apiSecret}`).toString('base64');
const customerId = 1

let data = JSON.stringify({
  "memo": "Memo",
  "customerMessage": "Message for customer",
  "customerUserId": 1111,
  "internalNotes": "Internal notes for Merchant reference",
  "invoiceNumber": "INV-NO-001",
  "amount": 0.01,
  "attachment": {
    "name": "Attachment",
    "content": "dGhpcyBpcyBhIHRlc3QgZmlsZSBvbmx5Lgo=",
    "mimeType": "text/plain"
  },
  "frequency": "Weekly",
  "endDate": "2025-01-01",
  "effectiveDate": "2025-01-01",
  "paymentTermValue": 12,
  "externalIdentifier": "ID-001"
});

let config = {
  method: 'post',
  maxBodyLength: Infinity,
  url: 'https://sandbox-api.securelyme.io/subscriptions/create',
  headers: { 
    'Content-Type': 'application/json', 
    'Authorization': `Basic ${encodedCredentials}`
  },
  data : data
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});

Attachments can be found on the Merchant dashboard, against the Subscription (or e-Bill).

Attachments

Attachments in the Merchant Dashboard can be viewed from within a subscription or e-bill


πŸͺNotifications of Payments

Securely.io sends notifications of subscription events (PENDING, ACTIVE, ACCEPTED, CANCELLED, PAYMENTREJECTED, DELETED, SUSPENDED, REQUESTEDCANCELLATION, VIEWED, EXPIRED, ENDED, COMPLETED) to the Webhook.

A Subscription Acceptance Expired response

{
  "PaymentExternalIdentifier":null,
  "PaymentRequestId":null,
  "EventCode":"SUBSCRIPTION_ACCEPTANCE_EXPIRED",
  "EventId":"5bce5628-665d-4a5e-b5ee-3d9fa1f6a174",
  "RecurringPaymentId":1,
  "RecurringPaymentExternalIdentifier":"SUBSCRIPTION-EXTERNAL-IDENTIFIER-FROM-MERCHANT"
}

A Subscription Acceptance response looks like this:

{
  "PaymentExternalIdentifier":null,
  "PaymentRequestId":null,
  "EventCode":"SUBSCRIPTION_ACCEPTED",
  "EventId":"ba09086e-67f3-4411-9c40-785dd78b13c9",
  "RecurringPaymentId":1,
  "RecurringPaymentExternalIdentifier":"SUBSCRIPTION-EXTERNAL-IDENTIFIER-FROM-MERCHANT"}

Suspending a Recurring Payment:

{
  "PaymentExternalIdentifier":null,
  "PaymentRequestId":null,
  "EventCode":"RECURRING_SUSPENDED",
  "EventId":"26042de3-d287-4862-b832-9ddb2df0a565",
  "RecurringPaymentId":1,
  "RecurringPaymentExternalIdentifier":"SUBSCRIPTION-EXTERNAL-ID-OF-SUBSCRIPTION-FROM-MERCHANT"
}