Portal

📘

Note

All functions are contract based. You need to acquire a separate token, which has a limited lifetime, for each contract. A description on how to retrieve an access token can be found here

The portal contains methods which enable you to serve your customer a rich set of possibilities to view and/or change their data, such as personal data, payment data and subscription data. To gather this data, you need to initialize the portal constructor with the token. If the token isn't valid, we return a 401 error. Given the token was valid, you now have a portal object which offers various methods. Most important, after initializing, the constructor is gathering contract details via contractDetails(). This method returns all the data needed to enrich your customer portal.

var portal = new SubscriptionJS.Portal(token);
var contractDetails = portal.contractDetails(
    function(data){
        //Fill your portal with the received data
    },
    function(error){
        //Does whatever an error handler does, e.g. display an error message to the user
    }
);

Change Personal Data

You may want to give your customers the ability to change their personal data connected to all of their contracts. Using customerChange() will do the trick for you! It consumes customerData but only works if you explicitly enable the option "Customers may change their own data via the default self-service portal" in Settings -> Self-Service -> Hosted Portal of the admin UI.

Be aware that this method resembles a PUT, not a PATCH!

var customerData = {
    emailAddress : "[email protected]",
    firstName : "John",
    lastName : "Doe",
    tag : "A53FD212-7879-44AD-923C-56DD20012100",
    companyName : "ACME, Inc.",
    vatId : "DE123465789",
    phoneNumber : "0123-45678",
    address : {
        "addressLine1": "c/o Coworking Ltd.",
        "street": "Torstrasse",
        "houseNumber": "89a",
        "postalCode": "10123",
        "city": "Berlin",
        "country": "DE"
    },
    locale : "en-US"
}

var customerChange = portal.customerChange(customerData,
    function(data){
        // Call contractDetails() again to get the updated data
    },
    function(error){
        //Does whatever an error handler does, e.g. display an error message to the user
    }
);

Change Payment Data

Besides changing the personal data, it's even more important to let the customer change his payment data himself, e.g. if payments are repeatedly failing. The portal, therefore, offers paymentChange() to set up a new payment method for the contract. Required are the SubscriptionJS payment service, as well as the new payment data.

var paymentService = new SubscriptionJS.Payment({
        publicApiKey: "5981a1e381b1fc126071xxxx",
        // For PSPs that rely on redirects (e.g. with checkout pages)
        providerReturnUrl: "https://yourReturnUrl.com"
    },
    function (data) {
        //initialized
        var secretPaymentData = {
            "bearer": "Debit:PayOne",
            "accountHolder": "John Doe",
            "iban": "DE8512345678259910xxxx"
        }

        portal.paymentChange(paymentService, secretPaymentData,
        function (data){
            // Everything went well, this returns (may differ from PSP to PSP)
            //{
            //  "ContractId": "5cd186af443e551fe8e4xxxx",
            //  "CustomerId": "5cd183b8443e551e4446xxxx",
            //  "GrossTotal": 1
            //}
        },
        function (error){
            //Does whatever an error handler does, e.g. display an error message to the user
        }
        );
    },
    function (error){
        //Does whatever an error handler does, e.g. display an error message to the user
    }
);

Payment For Up-/Downgrades

🚧

Limitations

For security reasons, you can't actually perform the up/downgrade solely through the frontend. Instead, you'll have to create an order from your backend using the REST API. Please read here.

You'll want to ensure that up- or downgrades the user requests are valid. For instance, a downgrade might not be allowed at this time or in conjunction with a given component that the customer is subscribed to. Since this type of business logic can generally be very complex, it makes sense to have the implementation on your side.

To pay for an up- or downgrade, you are able to use two workflows:

  • Paying for an up-/downgrade synchronously
  • Paying for an up-/downgrade interactively

Synchronous

Allows the customer to pay for an upgrade using the currently active payment method in a 'synchronous' fashion. The success method will be called only after the call to the PSP is successfully completed. This method is non-interactive; the user can't change the active payment method using this call.

var orderId = "5ce7eb000cefc277eaa3xxxx";
var paymentService = new SubscriptionJS.Payment({
    publicApiKey: "5981a1e381b1fc126071xxxx",
    providerReturnUrl: "https://yourReturnUrl.com"  // For PSPs that rely on redirects (e.g. with checkout pages)
    },
    function (data) {
        //initialized
        var paymentChange = portal.upgradePaySync(orderId,
            function (data){
            // Everything went well and returns
            //{
            //  "OrderId": "5ce7eb000cefc277eaa3xxxx",
            //  "ContractId": "5cd186af443e551fe8e4xxxx",
            //  "CustomerId": "5cd183b8443e551e4446xxxx",
            //  "GrossTotal": 1395.67,
            //  "OrderStatus": "PaymentPending"
            //}
            },
            function (error){
                //Does whatever an error handler does, e.g. display an error message to the user
            }
        );
    },
    function (error){
        //Does whatever an error handler does, e.g. display an error message to the user
    }
);

Interactive

Allows the customer to pay for an upgrade using new payment data. This method is interactive. Forward user to PSP page if URL is returned.

var order = { OrderId: "5ce7edfad5a49a0fdcc3xxxx", GrossTotal : 1677.53, Currency : "EUR"};
var paymentService = new SubscriptionJS.Payment({
    publicApiKey: "5981a1e381b1fc126071xxxx",
    providerReturnUrl: "https://yourReturnUrl.com"  // For PSPs that rely on redirects (e.g. with checkout pages)
    },
    function (data) {
        //initialized
        var secretPaymentData = {
            "bearer": "CreditCard:PayOne",
            "cardNumber": "401200103714xxxx",
            "expiryMonth": "12",
            "expiryYear": "2022",
            "cardHolder": "John Doe",
            "cvc": "123"
        }

        var paymentChange = portal.upgradePayInteractive(paymentService, secretPaymentData, order,
            function (data){
            // Everything went well and now forward your use to the returned url
            //{
            //    "OrderId": "5ce7edfad5a49a0fdcc3xxxx",
            //    "GrossTotal": 1677.53,
            //    "Url": "https://secure.pay1.de/3ds/redirect.php?md=2808xxxx&txid=33531xxxx",
            //    "Currency": "EUR",
            //    "OrderStatus": "PaymentPending"
            //}
                if(data.Url){
                    window.location.href = data.Url; //Forward to PSP page to pay
                }
            },
            function (error){
                //Does whatever an error handler does, e.g. display an error message to the user
            }
        );
    },
    function (error){
        //Does whatever an error handler does, e.g. display an error message to the user
    }
);

Cancel A Contract

As sad as the news may be, a customer may want to cancel his contract with you. Given you've set this in Settings -> Self-Service -> Hosted Portal -> "Allow Contract Cancellation", the portal allows you to make use of the method cancelContract(). It's simple to use as it contains only a success callback and an error callback and returns an object consisting of a message and an effective end date. The end date is set to the next possible end date.

{
  "Message": "Contract Cancelled",
  "EffectiveEndDate": "2020-04-04T09:40:13.0040000Z"
}

Logout

You may want to Invalidate a customer self-service token. The Portal offers a logout logout()

var portal = new SubscriptionJS.Portal(token);
portal.logout(
    function(){
        //You can perform any action upon successful completion, such as a redirect
    },
    function(error){
        //Does whatever an error handler does, e.g. display an error message to the user
    }
);