(function () { 'use strict'; var serviceId = 'paymentsDataContext'; var app = angular.module('payments'); function datacontext($q, $http, config, orgAdminService, $window, fsl) { var selectedPlan = {}; var additionalProperties = {}; var currencyOptions = [ { name: "£ GBP", symbol: "£", code: "gbp" }, { name: "$ USD", symbol: "$", code: "usd" }, { name: "€ EUR", symbol: "€", code: "eur" } ]; var myshowcaseImage = 'https://uiframework.mkmapps.com/latest/lib/products/myshowcase/images/stripe-logo.png'; var currentPaymentDetail; var service = { getHandler: getHandler, getPlans: getPlans, getSelectedPlan: getSelectedPlan, setSelectedPlan: setSelectedPlan, setAdditionalProperties: setAdditionalProperties, sendRequest: sendRequest, getCurrentPaymentDetails: getCurrentPaymentDetails, previewPlanUpgrade: previewPlanUpgrade, planUpgrade: planUpgrade, getInvoices: getInvoices, getCurrencyOptions: getCurrencyOptions, changeCard: changeCard, planCancel: planCancel, planEnable: planEnable, planRestart: planRestart, showStripeForNewAccount: showStripeForNewAccount, validateVat:validateVat }; return service; function validateVat(vatregno) { var request = $http({ method: "GET", url: 'https://apilayer.net/api/validate?access_key=b22a49e56f39a3b47fdd87acfac9e98b&vat_number='+vatregno+'&format=1' }); return (request.then(function (response) { return response.data.valid; }, handleError)); } function changeCard(email, billing) { var description = 'Update payment card'; var label = 'Change card'; if (!billing) { billing = false; } else { description = 'Update payment details'; label = 'Change details'; } return getHandler(handleTokenForChangeCard).open({ name: currentPaymentDetail.name, email: email, description: description, locale: 'auto', currency: currentPaymentDetail.currency, zipCode: true, amount: 0, panelLabel: label, image: myshowcaseImage, billingAddress: billing }); } function planRestart(email, users, cost, noVat) { additionalProperties = { 'Users': users }; selectedPlan = currentPaymentDetail; var label = '{{amount}} per ' + selectedPlan.frequency; if (!noVat) { label = label + ' excl. Tax'; } return getHandler().open({ name: currentPaymentDetail.name, email: email, description: users + ' Users @ ' + currentPaymentDetail.currencySymbol + (currentPaymentDetail.cost * 1.0 / 100) + ' per user per ' + currentPaymentDetail.frequency, locale: 'auto', currency: currentPaymentDetail.currency, zipCode: true, amount: cost, panelLabel: label, image: myshowcaseImage, billingAddress: true }); } function showStripeForNewAccount(plan, email, users, cost, noVat, euVat) { additionalProperties = { 'Users': users, 'noVAT': noVat }; if (euVat) { additionalProperties.euVAT = euVat; } selectedPlan = plan; var label = '{{amount}} per ' + plan.frequency; if (!noVat) { label = label + ' excl. Tax'; } return getHandler().open({ name: plan.name, email: email, description: users + ' Users @ ' + plan.currencySymbol + (plan.cost * 1.0 / 100) + ' per user per ' + plan.frequency, locale: 'auto', currency: plan.currency, zipCode: true, amount: cost, panelLabel: label, image: myshowcaseImage, billingAddress:true }); } function getCurrencyOptions() { return $q.resolve(currencyOptions); } function setAdditionalProperties(properties) { additionalProperties = properties; } var plans; var plansPromise; function getPlans() { if (!plans) { if (!plansPromise) { plansPromise = $http({ method: "GET", url: config.paymentsRemoteServiceUrl + 'api/applications/' + config.applicationId + '/plans' }).then(function (response) { plans = []; response.data.forEach(function(item) { plans.push(myPaymentsPlanToSimplePlan(item)); }); return plans; }, handleError); } return plansPromise; } return $q.resolve(plans); } function setSelectedPlan(plan) { selectedPlan = plan; } function getSelectedPlan() { return selectedPlan; } function handleError(response) { // The API response from the server should be returned in a // nomralized format. However, if the request was not handled by the // server (or what not handles properly - ex. server error), then we // may have to normalize it on our end, as best we can. if ( !angular.isObject(response.data) || !response.data.message ) { return ($q.reject("An unknown error occurred.")); } // Otherwise, use expected error message. return ($q.reject(response.data.message)); } function handleSuccess(response) { return (response.data); } function handleSuccessAndRedirect() { window.location = myShowcaseAdminSiteUrl + '#!/account/details'; return $window.location.reload(); } function getInvoices() { return orgAdminService.getCurrentOrg() .then(function (data) { var request = $http({ method: "GET", url: config.paymentsRemoteServiceUrl + 'api/organisationadministration/' + data.id + '/applications/' + config.applicationId + '/invoice' }); return (request.then(handleSuccess, handleError)); }); } function previewPlanUpgrade(updateData) { return orgAdminService.getCurrentOrg() .then(function (data) { var request = $http({ method: "POST", url: config.paymentsRemoteServiceUrl + 'api/organisationadministration/' + data.id + '/applications/' + config.applicationId + '/preview', data: { PlanId: updateData.planId, PlanProperties: updateData.properties } }); return (request.then(handleSuccess, handleError)); }); } function planUpgrade(token) { return orgAdminService.getCurrentOrg() .then(function (data) { var request = $http({ method: "POST", url: config.paymentsRemoteServiceUrl + 'api/organisationadministration/' + data.id + '/applications/' + config.applicationId + '/confirm', data: { Token: token } }); return (request.then(handleSuccessAndRedirect, handleError)); }); } function myPaymentsPlanToSimplePlan(data) { var simplePlan = { lastFour: data.LastFour, expiresYear: data.ExpiryDateYear, expiresMonth: data.ExpiryDateMonth, isFreePlan: data.IsFreePlan, name: data.PlanName, id: data.PlanId, PlanId: data.PlanId, cost: data.PlanCost, currency: data.PlanCurrency, frequency: data.PlanFrequency, quantity: data.PlanQuantity, minUsers: data.MinQuantity, maxUsers: data.MaxQuantity, cancelsAtPeriodEnd: data.CancelsAtPeriodEnd, cancelled: data.Cancelled, addressLine1: data.AddressLine1, addressLine2: data.AddressLine2, addressCity: data.AddressCity, addressCountry: data.AddressCountry, addressZip: data.AddressZip, addressState: data.AddressState, addressValid: data.AddressValid, addressName: data.AddressName, } simplePlan.currencySymbol = currencyOptions.filter(function (item) { return item.code === simplePlan.currency; })[0].symbol; if (simplePlan.isFreePlan) { simplePlan.status = "Free"; } else if (simplePlan.cancelled) { simplePlan.status = "Cancelled"; } else if (simplePlan.cancelsAtPeriodEnd) { simplePlan.status = "Cancelling"; } else { simplePlan.status = "Active"; } return simplePlan; } function getCurrentPaymentDetails() { if (!currentPaymentDetail) { return orgAdminService.getCurrentOrg() .then(function (data) { return getPaymentDetails(data.id) .then(function (data) { currentPaymentDetail = myPaymentsPlanToSimplePlan(data); return currentPaymentDetail; }); }); } return $q.resolve(currentPaymentDetail); } function getPaymentDetails(orgId) { var request = $http({ method: "get", url: config.paymentsRemoteServiceUrl + 'api/organisationadministration/' + orgId + '/applications/' + config.applicationId + '/plan' }); return (request.then(handleSuccess, handleError)); } function getHandler(afterFunction) { if (!afterFunction) { afterFunction = handleToken; } return StripeCheckout.configure({ key: config.publicKey, image: 'https://stripe.com/img/documentation/checkout/marketplace.png', locale: 'auto', token: afterFunction }); } function sendRequest(noRedirect, organisationId) { if (!organisationId) { return orgAdminService.getCurrentOrg() .then(function (data) { var request = $http({ method: "post", url: config.paymentsRemoteServiceUrl + 'api/organisationadministration/' + data.id + '/applications/' + config.applicationId + '/plan', data: { PlanId: selectedPlan.PlanId, PlanProperties: additionalProperties } }); if (noRedirect) { return (request.then(handleSuccess, handleError)); } else { return (request.then(handleSuccessAndRedirect, handleError)); } }); } else { var request = $http({ method: "post", url: config.paymentsRemoteServiceUrl + 'api/organisationadministration/' + organisationId + '/applications/' + config.applicationId + '/plan', data: { PlanId: selectedPlan.PlanId, PlanProperties: additionalProperties } }); if (noRedirect) { return (request.then(handleSuccess, handleError)); } else { return (request.then(handleSuccessAndRedirect, handleError)); } } } function changeDetails(noRedirect) { return orgAdminService.getCurrentOrg() .then(function (data) { var request = $http({ method: "PUT", url: config.paymentsRemoteServiceUrl + 'api/organisationadministration/' + data.id + '/billing', data: { Properties: additionalProperties } }); if (noRedirect) { return (request.then(handleSuccess, handleError)); } else { return (request.then(handleSuccessAndRedirect, handleError)); } }); } function planCancel(noRedirect) { return orgAdminService.getCurrentOrg() .then(function (data) { var request = $http({ method: "DELETE", url: config.paymentsRemoteServiceUrl + 'api/organisationadministration/' + data.id + '/applications/' + config.applicationId + '/plan' }); if (noRedirect) { return (request.then(handleSuccess, handleError)); } else { return (request.then(handleSuccessAndRedirect, handleError)); } }); } function planEnable(noRedirect) { return orgAdminService.getCurrentOrg() .then(function (data) { var request = $http({ method: "POST", url: config.paymentsRemoteServiceUrl + 'api/organisationadministration/' + data.id + '/applications/' + config.applicationId + '/plan/enable' }); if (noRedirect) { return (request.then(handleSuccess, handleError)); } else { return (request.then(handleSuccessAndRedirect, handleError)); } }); } function handleToken(token) { // You can access the token ID with `token.id`. // Get the token ID to your server-side code for use. // At this point, we need to send the token to our code // the server side needs to create a stripe customer // and adds that customer to the subscription. // stripe then attempts to bill the customer, and tells the server if it works. //the server then needs to tell us the result. //So process is: Post to method, then wait for signalr result. //the signalr bit isn't done, so just do a page refresh //Spinner needed here fsl.show("Processing payment"); additionalProperties["Token"] = token.id; return sendRequest(); } function handleTokenForChangeCard(token) { fsl.show("Changing payment details"); additionalProperties["Token"] = token.id; return changeDetails(); } } app.factory(serviceId, ['$q', '$http', 'paymentsConfig', 'OrganisationAdminService', '$window', 'fullScreenLoaderContext', datacontext]); })();