Files
portal_v3/portal/api-sandbox/sdk/js/afssdk-dev.js
equippedcoding-master 1c59875b8a initial commit 2
2025-09-17 15:19:57 -05:00

3641 lines
144 KiB
JavaScript

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
global.AFSSdk = factory()
}(this, (function () { //'use strict';
let fetchJsonp = initializeJsonp();
let applicationManager = null;
let api_container = null;
let PaymentsPayPal = initpayment_paypal();
let PaymentsStripe = initpayment_stripe();
let EmailHandler = initemail_handler();
function InitializeClientSDK(public_key,cb,mode){
if(mode==undefined){mode = "production";}
(async function() {
let url = `https://api.appfactory.studio/v1/core/initialize_client_sdk?key=${public_key}`;
if(mode=="development" || mode=="dev"){
url = `https://api-sandbox.appfactory.studio/v1/core/initialize_client_sdk?key=${public_key}`;
}
try {
let options = {method: "GET"};
const response = await fetch(url,options);
if (!response.ok) { throw new Error(`Response status: ${response.status}`); }
const json = await response.json();
if(cb!=undefined){
if(json.authorized==false){
throw new Error("AFS SDK NOT initialized!");
}
applicationManager = new ApplicationManager(json,mode);
applicationManager.getConfig(function(mainconfig){
// localStorage.setItem("afssdk", JSON.stringify(json));
// console.log(json);
// console.log(mainconfig);
cb(json);
});
}
} catch (error) {
console.log(error);
}
})();
}
function phpcall(params,cb){
// https://stackoverflow.com/questions/9713058/send-post-data-using-xmlhttprequest
let http = new XMLHttpRequest();
// let params = 'api_direct_payment=true&name=binny';
// let params = new Object();
// params.api_direct_payment = true;
let urlEncodedData = "", urlEncodedDataPairs = [], name;
for( name in params ) {
urlEncodedDataPairs.push(encodeURIComponent(name)+'='+encodeURIComponent(params[name]));
}
const URL = "/portal/admin/core/api/php/request.php";
http.open('POST', URL, true);
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
cb(JSON.parse(http.responseText));
}
}
// console.log(urlEncodedDataPairs.join("&"));
http.send(urlEncodedDataPairs.join("&"));
}
class ApplicationManager {
constructor(api,mode){
const self = this;
self.environment = mode;
self.config = api;
self.domain_settings = null;
self.managed_domain = null;
}
getConfig(cb){
const self = this;
if(applicationManager==null) {
console.log("Appfactory Studio: SDK has not been initialized!");
return;
}
applicationManager.apicall("/v1/core/member_get_config",{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body:JSON.stringify({subdomain: self.config.api.json.subdomain})
},function(config){
console.log(config);
self.domain_settings = config.configuration.domain_settings[0];
self.managed_domain = config.domain;
if(cb!=undefined) cb(config);
});
}
apicall(path,options,cb){
const self = this;
if(options.headers==undefined){
options["headers"] = {
'Content-Type': 'application/json'
};
}
let myid = null;
// options.headers["Access-Control-Allow-Origin"] = "*";
options.headers["Authorization"] = `token ${self.config.key}`;
(async function() {
let url_prefix = `https://api`;
if(self.environment=="development"){
url_prefix = `https://api-sandbox`;
}
const url = `${url_prefix}.${self.config.api.json.url}${path}`;
console.log(self.config);
try {
// if(options==undefined || options==null){ options = {method: "GET"};}
const response = await fetch(url,options);
if (!response.ok) { throw new Error(`Response status: ${response.status}`); }
const json = await response.json();
if(cb!=undefined){
myid = cb(json);
}
} catch (error) {
console.log(error);
console.error(error);
}
})();
return myid;
}
init(){
phpcall({},function(){
});
}
}
function sendEmail(id){
if(applicationManager==null) {
console.log("Appfactory Studio: SDK has not been initialized!");
return;
}
applicationManager.apicall("/v1/core/send_email",{
method: 'POST',
environment: applicationManager.environment,
headers: {
'Content-Type': 'application/json'
},
body:JSON.stringify({id})
},function(config){
// console.log(config);
});
}
function createNewDirectPayment(){ return new DirectPayments(applicationManager); }
class DirectPayments {
constructor(appManager){
this.appManager = appManager;
this.configurations = null;
this.email_handler = null;
this.processor = null;
this.current_processor_name = "";
this.current_processor_object = null;
this.stripeProcessor = null;
this.subscriptionsManager = null;
}
initialize(key_id,cb){
let self = this;
if(applicationManager==null) {
console.log("Appfactory Studio: SDK has not been initialized!");
return;
}
applicationManager.apicall("/v1/payments/initialize_direct_payments",{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body:JSON.stringify({key_id})
},function(config){
console.log(config);
self.configurations = config;
if(config.message!=undefined && config.message=="error"){
console.log("Error no direct payment");
return;
}
if(config.processor.json.processor=="stripe"){
self.processor = self._init_stripe();
self.current_processor_name = config.processor.processor_name;
self.subscriptionsManager = new SubscriptionsManager(config.processor);
}
if(config.processor.json.processor=="paypal"){
self.processor = self._init_paypal(config.processor);
}
if(config.processor.json.processor=="square"){
}
if(self.processor==null){
console.log("No processor selected!");
}
if(cb!=undefined) cb(self.processor);
});
}
initializeSubscription(groupname,cb){
let self = this;
console.log(self.configurations.direct_payment.json);
self.subscriptionsManager.setup(groupname, self.configurations.direct_payment.json.configuration.recurring);
let group = self.subscriptionsManager.getProcessorGroup(groupname);
let lookup_keys = self.subscriptionsManager.getLookupKeys(group);
// console.log(lookup_keys);
self.processor.getSubscriptions(lookup_keys,cb,self);
}
initializeTier(options,cb){
this.processor.createMembershipTier(options,cb,this);
}
setupView(data,selection,app,onStartCB,onFinishCB) {
return this.processor.setupView(data,selection,app,onStartCB,onFinishCB,this);
}
createCustomer(props,cb){
this.processor.createCustomer(props,cb,this);
}
setupSubscription(props,cb){
this.processor.createSubscription(props,cb,this);
}
getProcessorName(){
return this.configurations.processor.json.nameid;
}
getProcessorGroupName(){
// console.log(this);
return this.subscriptionsManager.group_name;
}
setEmailHandler(handler){
this.email_handler = handler;
}
getDirectPayment(){
return this.configurations.direct_payment;
}
saveEmailHandlersForPayment(payment_intent,cb){
// 77777
let self = this;
// console.log(self.email_handler);
console.log({
"direct_payment": self.getDirectPayment().json,
"mail_handlers": self.email_handler.handler.handlers,
"payment_intent": payment_intent
});
self.appManager.apicall("/v1/payments/save_handler",{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
// "api_save_email_handlers_for_payment_intent": true,
"direct_payment": JSON.stringify(self.getDirectPayment().json),
"mail_handlers": JSON.stringify(self.email_handler.handler.handlers),
"payment_intent": JSON.stringify(payment_intent)
})
},function(resp){
if(cb!=undefined) cb(resp);
});
// phpcall({
// "api_save_email_handlers_for_payment_intent": true,
// "direct_payment": JSON.stringify(self.getDirectPayment().json),
// "mail_handlers": JSON.stringify(self.email_handler.handler.handlers),
// "payment_intent": JSON.stringify(payment_intent)
// },function(resp){
// if(cb!=undefined) cb(resp);
// });
}
build(props){
_make(props,this,function(){
});
}
useEmailGroup(id,emails,variables,callback){
// 77777
const self = this;
let handlersClone = structuredClone(self.getDirectPayment().json.mail_handlers);
let managed_domain = applicationManager.managed_domain;
let domain_settings = applicationManager.domain_settings;
console.log("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
console.log(self.getDirectPayment());
console.log(handlersClone);
console.log(managed_domain);
console.log(domain_settings);
self.email_handler = new EmailHandler(id,handlersClone,domain_settings,managed_domain);
if(self.email_handler.handler==null){
console.log(`Error No email group found for ${id}`);
}
self.email_handler.setupVariables(emails,variables);
}
getProcessor(){
return this.processor;
}
_init_paypal(processor){
return new PayPalProcessor(processor,this);
}
_init_stripe(){
let self = this;
// console.log("initializing stripe payment processor...");
if(document.getElementById("stripe_script_tag_id")==null){
const script = document.createElement('script');
script.src = 'https://js.stripe.com/v3/';
script.id = "stripe_script_tag_id";
document.head.appendChild(script);
}
// console.log(self);
// console.log(self.configurations);
self.stripeProcessor = new PaymentsStripe(self.configurations.processor, self, self.configurations.managed_domain);
return self.stripeProcessor;
}
///////////////////////////
}
/**
* Main class to handle processors.
*/
class Processor {
constructor(){
}
setupCheckout(opts){}
createProcessor(){
}
}
class PayPalProcessor extends Processor {
constructor(processor,dp){
super();
let self = this;
self.processor = processor;
self.dp = dp;
console.log(dp);
}
setupCheckout(opts){
const self = this;
let options = __setupOptions(opts,self);
if(document.getElementById("paypal_script_tag_id")==null){
const PAYPAL_CLIENT_ID = self.processor.json.client_id;
const script = document.createElement('script');
script.src = `https://www.paypal.com/sdk/js?components=buttons,card-fields&client-id=${encodeURIComponent(PAYPAL_CLIENT_ID)}`;
script.id = "paypal_script_tag_id";
document.head.appendChild(script);
}
setTimeout(() => {
let id = opts.containerId;
if(document.querySelector(id)){
setTimeout(() => {
console.log(options);
document.querySelector(id).innerHTML = self.__html_card(options);
},2000);
__runPaypal(options,self);
}else{
console.error(`Can not attach, element ${id} does not exist`);
}
},1000);
}
__runPaypal2(){
const self = this;
function RunCreatePaypalPayment(){
async function createOrderCallback() {
try {
const response = await fetch(`${MY_URL}/payments/paypal/orders`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
// use the "body" param to optionally pass additional order information
// like product ids and quantities
body: JSON.stringify({
cart: [
{
id: "YOUR_PRODUCT_ID",
quantity: "YOUR_PRODUCT_QUANTITY",
},
],
}),
});
const orderData = await response.json();
if (orderData.id) {
return orderData.id;
} else {
const errorDetail = orderData?.details?.[0];
const errorMessage = errorDetail
? `${errorDetail.issue} ${errorDetail.description} (${orderData.debug_id})`
: JSON.stringify(orderData);
throw new Error(errorMessage);
}
} catch (error) {
console.error(error);
resultMessage(`Could not initiate PayPal Checkout...<br><br>${error}`);
}
}
async function onApproveCallback(data, actions) {
try {
const response = await fetch(`${MY_URL}/payments/paypal/orders/${data.orderID}/capture`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
const orderData = await response.json();
// Three cases to handle:
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// (2) Other non-recoverable errors -> Show a failure message
// (3) Successful transaction -> Show confirmation or thank you message
const transaction =
orderData?.purchase_units?.[0]?.payments?.captures?.[0] ||
orderData?.purchase_units?.[0]?.payments?.authorizations?.[0];
const errorDetail = orderData?.details?.[0];
// this actions.restart() behavior only applies to the Buttons component
if (errorDetail?.issue === "INSTRUMENT_DECLINED" && !data.card && actions) {
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// recoverable state, per https://developer.paypal.com/docs/checkout/standard/customize/handle-funding-failures/
return actions.restart();
} else if (
errorDetail ||
!transaction ||
transaction.status === "DECLINED"
) {
// (2) Other non-recoverable errors -> Show a failure message
let errorMessage;
if (transaction) {
errorMessage = `Transaction ${transaction.status}: ${transaction.id}`;
} else if (errorDetail) {
errorMessage = `${errorDetail.description} (${orderData.debug_id})`;
} else {
errorMessage = JSON.stringify(orderData);
}
throw new Error(errorMessage);
} else {
// (3) Successful transaction -> Show confirmation or thank you message
// Or go to another URL: actions.redirect('thank_you.html');
resultMessage(
`Transaction ${transaction.status}: ${transaction.id}<br><br>See console for all available details`,
);
console.log(
"Capture result",
orderData,
JSON.stringify(orderData, null, 2),
);
}
} catch (error) {
console.error(error);
resultMessage(
`Sorry, your transaction could not be processed...<br><br>${error}`,
);
}
}
window.paypal.Buttons({
createOrder: createOrderCallback,
onApprove: onApproveCallback,
}).render("#paypal-button-container");
const cardField = window.paypal.CardFields({
createOrder: createOrderCallback,
onApprove: onApproveCallback,
});
// Render each field after checking for eligibility
if (cardField.isEligible()) {
const nameField = cardField.NameField();
nameField.render("#card-name-field-container");
const numberField = cardField.NumberField();
numberField.render("#card-number-field-container");
const cvvField = cardField.CVVField();
cvvField.render("#card-cvv-field-container");
const expiryField = cardField.ExpiryField();
expiryField.render("#card-expiry-field-container");
// Add click listener to submit button and call the submit function on the CardField component
document
.getElementById("card-field-submit-button")
.addEventListener("click", () => {
cardField
.submit({
// From your billing address fields
billingAddress: {
addressLine1: document.getElementById("card-billing-address-line-1")
.value,
addressLine2: document.getElementById("card-billing-address-line-2")
.value,
adminArea1: document.getElementById(
"card-billing-address-admin-area-line-1",
).value,
adminArea2: document.getElementById(
"card-billing-address-admin-area-line-2",
).value,
countryCode: document.getElementById(
"card-billing-address-country-code",
).value,
postalCode: document.getElementById(
"card-billing-address-postal-code",
).value,
},
})
.catch((error) => {
resultMessage(
`Sorry, your transaction could not be processed...<br><br>${error}`,
);
});
});
} else {
// Hides card fields if the merchant isn't eligible
document.querySelector("#card-form").style = "display: none";
}
// Example function to show a result to the user. Your site's UI library can be used instead.
function resultMessage(message) {
const container = document.querySelector("#result-message");
container.innerHTML = message;
}
}
RunCreatePaypalPayment();
}
__payaplCheckOutHtmlElement(paypal_style,self){
let showpaypalbutton = "";
if(self.options.showPaypalButton){
showpaypalbutton = `
<div class="row">
<div class="">
<div id="paypal-button-container" class="paypal-button-container"></div>
</div>
</div>
`;
}
let or = "";
if(self.options.showPaypalForm && self.options.showPaypalButton){
or = `
<div class="row justify-content-center">
<div class="">
<div><p style="text-align: center;">or</p></div>
</div>
</div>
`;
}
let showpaypalform = "";
if(self.options.showPaypalForm){
showpaypalform = `
<div class="row justify-content-center">
<div class="">
<div class="card_container">
<form id="card-form">
<label for="card-number">Card Number</label>
<div id="card-number" class="card_field"></div>
<div style="display: flex; flex-direction: row;">
<div>
<label for="expiration-date">Expiration Date</label>
<div id="expiration-date" class="card_field"></div>
</div>
<div style="margin-left: 10px;">
<label for="cvv">CVV</label>
<div id="cvv" class="card_field"></div>
</div>
</div>
${getBillingAddressNameHtml(self)}
${getBillingAddressHtml(self)}
<div>
<input
type="text"
id="card-billing-address-zip"
name="card-billing-address-zip"
autocomplete="off"
placeholder="zip / postal code"
/>
</div>
<!--
<div>
<input
type="text"
id="card-billing-address-country"
name="card-billing-address-country"
autocomplete="off"
placeholder="country code"
/>
-->
</div>
<br />
${self.options.onSubmit.htmlButton}
${self.options.termsAgreementText}
</form>
</div>
</div>
</div>
`;
}
return `
${paypal_style()}
<div id="payment-container" class="payment-container">
<div class="">
<div><p id="payment-status-message-title"></p></div>
${showpaypalbutton}
${or}
${showpaypalform}
</div><!--Container-->
</div><!--payment-container-->
`;
}
__setupOptions(self,obj){
self.container_id = obj.container_id;
self.callbacks = {};
self.contents = {};
// options
if(obj.options==undefined){
obj.options = {};
}
obj.options.process = {};
if(obj.options.delay==undefined){
obj.options.delay = 500;
}
if(obj.options.container_id==undefined){
obj.options.container_id = "";
}
if(obj.options.appendNow==undefined){
obj.options.appendNow = true;
}
if(obj.options.showPaypalForm==undefined){
obj.options.showPaypalForm = true;
}
if(obj.options.showPaypalButton==undefined){
obj.options.showPaypalButton = true;
}
if(obj.options.paypal_error_message==undefined){
obj.options.paypal_error_message = "Sorry there was an error process your payment.";
}
if(obj.options.submit_button==undefined){
obj.options.submit_button = {id:"defualt_submit_button_id",label:"Submit"};
}
if(obj.options.onSubmit==undefined){
obj.options.onSubmit = {
id:"defualt_submit_button_id",
label:"Submit",
showButton:true
};
}
if(obj.options.termsAgreementText==undefined){
obj.options.termsAgreementText = `<div class="mt-3 d-flex justify-content-center">By clicking Donate you agree to the <a id="paypal_terms_and_conditions" href="#">Terms & Conditions</a></p></div>`;
}
if(obj.options.onSubmit.showButton==undefined || obj.options.onSubmit.showButton==true){
obj.options.onSubmit.htmlButton = `<button value="submit" id="${obj.options.onSubmit.id}" style="width: 100%; color: white" class="btn btn-success ${obj.options.submit_button.className}"><strong>${obj.options.onSubmit.label}</strong></button>`;
}else{
obj.options.onSubmit.htmlButton = "";
}
if(obj.options.overlayDelay==undefined){
obj.options.overlayDelay = 20000;
}
if(obj.options.billingAddressEnabled==undefined){
obj.options.billingAddressEnabled = false;
}
if(obj.options.billingAddressNameEnabled==undefined){
obj.options.billingAddressNameEnabled = false;
}
if(obj.options.no_reply_subject==undefined){
obj.options.no_reply_subject = "";
}
self.options = obj.options;
// contents
if(obj.success_content==undefined){
obj.success_content = function(mydata){ return ""; };
}
self.contents.success_content = obj.success_content;
// callbacks
if(obj.success_callback==undefined){
obj.success_callback = function(){};
}
self.callbacks.success_callback = obj.success_callback;
if(obj.error_callback==undefined){
obj.error_callback = function(erre){};
}
self.callbacks.error_callback = obj.error_callback;
if(obj.validation_callback==undefined){
console.log("validation_callback callbck not set");
obj.validation_callback = function(){return {pass:true}}
}
self.callbacks.validation_callback = obj.validation_callback;
if(obj.validate_price_callback==undefined){
console.log("validate_price_callback callbck not set");
obj.validation_callback = function(){return {pass:true}}
}
self.callbacks.validate_price_callback = obj.validate_price_callback;
if(obj.success_content==undefined){
console.log("success_content callbck not set");
obj.success_content = function(){return {pass:true}}
}
self.callbacks.success_content = obj.success_content;
if(obj.button_onApprove_callback==undefined){
obj.button_onApprove_callback = function(){};
}
self.callbacks.button_onApprove_callback = obj.button_onApprove_callback;
if(obj.button_onClick_callback==undefined){
obj.button_onClick_callback = function(){};
}
self.callbacks.button_onClick_callback = obj.button_onClick_callback;
}
__getBillingAddressNameHtml(self){
var name = "";
if(self.options.billingAddressNameEnabled){
name = `
<label for="card-holder-name">Name on Card</label>
<input
type="text"
id="card-holder-name"
name="card-holder-name"
autocomplete="off"
placeholder="card holder name"
/>
`;
}
return name;
}
__getBillingAddressHtml(self){
var billingAddressHtml = "";
if(self.options.billingAddressEnabled){
billingAddressHtml = `
<div>
<label for="card-billing-address-street">Billing Address</label>
<input
type="text"
id="card-billing-address-street"
name="card-billing-address-street"
autocomplete="off"
placeholder="street address"
/>
</div>
<div>
<label for="card-billing-address-unit">&nbsp;</label>
<input
type="text"
id="card-billing-address-unit"
name="card-billing-address-unit"
autocomplete="off"
placeholder="unit"
/>
</div>
<div>
<input
type="text"
id="card-billing-address-city"
name="card-billing-address-city"
autocomplete="off"
placeholder="city"
/>
</div>
<div>
<input
type="text"
id="card-billing-address-state"
name="card-billing-address-state"
autocomplete="off"
placeholder="state"
/>
</div>
`;
}
return billingAddressHtml;
}// end getBillingAddressHtml
__html_card(opts){
return `
<div>
<style>
.paypal-button-container {
border-radius: 5px;
background-color: #FFFFFF;
padding: 20px;
max-width: 760px;
width: 100%;
margin: 0 auto;
}
.card_container {
border-radius: 5px;
background-color: #FFFFFF;
padding: 20px;
max-width: 760px;
width: 100%;
margin: 0 auto;
}
.card_field{
width: 100%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-top: 6px;
margin-bottom: 16px;
resize: vertical;
height:40px;
background:white;
font-size:17px;
color:#3a3a3a;
font-family:helvetica, tahoma, calibri, sans-serif;
}
.card_field_50{
width: 50%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-top: 6px;
margin-bottom: 16px;
resize: vertical;
height:40px;
background:white;
font-size:17px;
color:#3a3a3a;
font-family:helvetica, tahoma, calibri, sans-serif;
}
.card_field_75{
width: 75%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-top: 6px;
margin-bottom: 16px;
resize: vertical;
height:40px;
background:white;
font-size:17px;
color:#3a3a3a;
font-family:helvetica, tahoma, calibri, sans-serif;
}
.row {
display: -ms-flexbox; /* IE10 */
display: flex;
-ms-flex-wrap: wrap; /* IE10 */
flex-wrap: wrap;
margin: 0 -16px;
}
.col-25 {
-ms-flex: 25%; /* IE10 */
flex: 25%;
}
.col-50 {
-ms-flex: 50%; /* IE10 */
flex: 50%;
}
input[type=text], select, textarea {
width: 100%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-top: 6px;
margin-bottom: 16px;
resize: vertical;
height:40px;
background:white;
font-size:17px;
color:#3a3a3a;
font-family:helvetica, tahoma, calibri, sans-serif;
}
input[type=submit] {
background-color: #4CAF50;
color: white;
padding: 12px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.message_container {
border-radius: 5px;
background:#FFFFFF;
font-size:13px;
font-family:monospace;
padding: 20px;
}
#loading {
width: 100%;
height: 100%;
top: 0;
left: 0;
position: fixed;
display: block;
opacity: 0.7;
background-color: #fff;
z-index: 99;
text-align: center;
}
#loading-image {
position: absolute;
z-index: 15;
top: 50%;
left: 50%;
margin: -100px 0 0 -150px;
}
.spinner {
position: fixed;
top: 50%;
left: 50%;
margin-left: -50px; /* half width of the spinner gif */
margin-top: -50px; /* half height of the spinner gif */
text-align:center;
z-index:1234;
overflow: auto;
width: 100px; /* width of the spinner gif */
height: 102px; /* height of the spinner gif +2px to fix IE8 issue */
}
.button_container {
display: flex;
justify-content: center;
}
button:hover {
background-color: powderblue;
}
button {
width:229px;
height:49px;
background:lightblue;
border:1px dotted black;
font-size:17px;
color:#3a3a3a;
padding: 12px 20px;
border-radius: 4px;
cursor: pointer;
margin: 0 auto;
}
.btn_small{
width:130px;
height:39px;
background:lightblue;
border:1px dotted black;
font-size:14px;
color:#3a3a3a;
}
.btn_small:hover {
background-color: powderblue;
}
</style>
<div id="paypal-button-container" class="paypal-button-container"></div>
<!-- Containers for Card Fields hosted by PayPal -->
<div id="card-form" class="card_container">
<div id="card-name-field-container"></div>
<div id="card-number-field-container"></div>
<div id="card-expiry-field-container"></div>
<div id="card-cvv-field-container"></div>
<!-- To be replaced with your own Billing Address Fields -->
<div>
<label for="card-billing-address-line-1">Billing Address</label>
<input
type="text"
id="card-billing-address-line-1"
name="card-billing-address-line-1"
autocomplete="off"
placeholder="Address line 1"
/>
</div>
<div>
<input
type="text"
id="card-billing-address-line-2"
name="card-billing-address-line-2"
autocomplete="off"
placeholder="Address line 2"
/>
</div>
<div>
<input
type="text"
id="card-billing-address-admin-area-line-1"
name="card-billing-address-admin-area-line-1"
autocomplete="off"
placeholder="Admin area line 1"
/>
</div>
<div>
<input
type="text"
id="card-billing-address-admin-area-line-2"
name="card-billing-address-admin-area-line-2"
autocomplete="off"
placeholder="Admin area line 2"
/>
</div>
<div>
<input
type="text"
id="card-billing-address-country-code"
name="card-billing-address-country-code"
autocomplete="off"
placeholder="Country code"
/>
</div>
<div>
<input
type="text"
id="card-billing-address-postal-code"
name="card-billing-address-postal-code"
autocomplete="off"
placeholder="Postal/zip code"
/>
</div>
<br /><br />
<button id="card-field-submit-button" type="button">
Press
</button>
</div>
</div>
`;
}
}
class SubscriptionsManager {
constructor(processor){
this.processors = [processor];
this.access = null;
this.access = null;
this.groups = [];
this.group_name = "";
}
setup(group_processor, groups){
this.group_name = group_processor;
this.groups = groups;
// console.log(nameid);
// console.log(configurations);
// let selectedMembership = null;
// for (let i = 0; i < configurations.length; i++) {
// const configs = configurations[i];
// for (let n = 0; n < configs.length; n++) {
// const element = configs[n];
// if(element.json.nameid==nameid){
// selectedMembership = element;
// break;
// }
// }
// }
// self._raw_access = selectedMembership;
// self.access = selectedMembership.json;
}
getGroups(){
return this.access.groups;
}
getProcessorGroup(group_processor){
let self = this;
let processors = self.processors;
let gpprocessor = null;
let groups = self.groups;
// console.log(group_processor);
for (let i = 0; i < groups.processors.length; i++) {
const processor = groups.processors[i];
if(processor.name==group_processor){
gpprocessor = processor;
break;
}
}
if(gpprocessor==null) return gpprocessor;
// let authorizations = null;
let subscriptions = null;
// for (let i = 0; i < self.access.groups.authorizations.length; i++) {
// const _auth = self.access.groups.authorizations[i];
// if(gpprocessor.authorization_group==_auth.name){
// authorizations = _auth;
// break;
// }
// }
// console.log(self.access);
for (let i = 0; i < groups.subscriptions.length; i++) {
const _sub = groups.subscriptions[i];
if(gpprocessor.subscription_group==_sub.name){
subscriptions = _sub;
break;
}
}
let processor_config = null;
if(processors!=undefined){
console.log(processors);
for (let i = 0; i < processors.length; i++) {
const _proc = processors[i].json;
if(_proc.nameid==gpprocessor.processor_nameid){
processor_config = _proc;
break;
}
}
}
self.group = {
"processor_config": processor_config,
"processor_group": gpprocessor,
// "authorizations": authorizations,
"subscriptions": subscriptions
}
return self.group;
}
getLookupKeys(group){
let self = this;
let lookup_keys = [];
for (let i = 0; i < group.subscriptions.tiers.length; i++) {
const tier = group.subscriptions.tiers[i];
if(tier.lookup_key=="_none_" || tier.lookup_key=="" || tier.lookup_key==undefined || tier.lookup_key==null) continue;
lookup_keys.push(tier.lookup_key);
}
return lookup_keys;
}
getGroupFeature(groupId,membership){
let self = this;
let group_subscription = null;
for (let i = 0; i < access_settings.groups.subscriptions.length; i++) {
const subscription = access_settings.groups.subscriptions[i];
if(subscription.name==groupId){
group_subscription = subscription;
break;
}
}
// extra.current.access.access_settings.json.groups.authorizations
let group_authorizations = null;
for (let i = 0; i < access_settings.groups.authorizations.length; i++) {
const auth = access_settings.groups.authorizations[i];
for (let n = 0; n < auth.apps.length; n++) {
const app = auth.apps[n];
app.features[0]
}
}
return this.access_settings.groups;
}
getTier(tierId,group){
let tier = group.subscriptions.tiers[tierId];
return tier;
}
}
function initpayment_paypal(){
class PaymentsPayPal {
constructor(pay, app, service) {
this._props_ = {};
this.pay = pay;
this.app = app;
this.service = service;
}
setupCheckout(opts) {
let self = this;
setupOptions(self, opts);
if (self.options.appendNow) {
self.appendPaypal();
}
}
reset() {
__setup_paypal(this.app, this.service);
}
check(cb) {
let self = this;
async function _check_paypal_service(cb, self) {
let data = { checking: true };
fetchJsonp(self.pay.service_request_url + "?" + new URLSearchParams({ type: "check", data: JSON.stringify(data) }), {
method: "get",
timeout: 5000
})
.then(resp => resp.json())
.then((response) => {
// console.log(response);
cb(response);
}).catch((err) => {
console.log(err);
cb(false, err);
});
}
_check_paypal_service(cb, self);
}
setupLink(opts) {
let self = this;
var settings = {
"url": self.pay.service_request_url,
'cache': false,
'dataType': "jsonp",
"async": true,
"crossDomain": true,
"method": "GET",
"data": { type: "generate_token" },
"headers": {
"accept": "application/json",
"Access-Control-Allow-Origin": "*"
}
};
if (opts.params == undefined) {
opts.params = "components=buttons,hosted-fields";
}
$.ajax(settings).done(function (response) {
// console.log(response);
response = JSON.parse(response);
if (opts.log != undefined && opts.log == true) {
// console.log(response);
}
let clientId = response.clientId;
let clientToken = response.clientToken;
let paypal_element_id = "paypal_script_element";
if (document.getElementById(paypal_element_id) != undefined) {
document.getElementById(paypal_element_id).remove();
}
// let url = `<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&vault=true&intent=subscription"></script>`; // Add your client_id
//let url = `<script src="https://www.paypal.com/sdk/js?components=buttons,hosted-fields&client-id=${clientId}" data-client-token="${clientToken}"></script>`;
let script = document.createElement("script");
script.id = paypal_element_id;
script.src = "https://www.paypal.com/sdk/js?"
+ opts.params
+ "&client-id=" + clientId;
script.dataset.clientToken = clientToken;
document.head.appendChild(script);
if (opts.callback != undefined && typeof opts.callback == 'function') {
try {
if (typeof paypal == undefined) {
console.log("PayPal is undefined, reinitializing paypal...");
$("#" + paypal_element_id).remove();
document.head.appendChild(script);
}
setTimeout(() => { opts.callback(true); }, 500);
} catch (e) {
console.log("Reinitializing paypal...");
console.error(e);
$("#" + paypal_element_id).remove();
document.head.appendChild(script);
setTimeout(() => { opts.callback(true); }, 500);
}
}
}).fail(function (msg) {
opts.callback(false, msg);
});
}
_paypal_init() {
var self = this;
// paypal link is added dynamically in main.js, give it time to download
setTimeout(function () {
if (self.options.showPaypalButton == true) {
// TODO_3: paypal initialiation
setupPaypalButtons(self);
}
if (self.options.showPaypalForm == true) {
setupPaypalHostedFields(self);
}
}, 500);
}
appendPaypal() {
let self = this;
let paypalelement = payaplCheckOutHtmlElement(paypal_style, self);
$("#" + self.container_id).empty();
$("#" + self.container_id).append(paypalelement);
setTimeout(function () {
self._paypal_init();
}, 3000);
// }, self.options.delay);
}
}
function _buildPaymentObject(receiptStub,orderData,app,self){
let processor = null;
for(let i=0; i < app.extra.config.configurations.payments.length; i++){
if(receiptStub.processor_type==app.extra.config.configurations.payments[i].json.processor){
if(app.extra.config.configurations.payments[i].json.active){
processor = app.extra.config.configurations.payments[i].json;
break;
}
}
}
if(processor==null){ return null; }
console.log(processor);
console.log(receiptStub);
console.log(orderData);
receipt = {};
receipt.set = true;
receipt.reference_num = receiptStub.reference_num;
receipt.create_time = orderData.purchase_units[0].payments.captures[0].create_time;
// TODO: Stripe implementation
//
if(orderData.purchase_units[0].payments.captures[0].seller_receivable_breakdown==undefined){
receipt.gross_amount = orderData.purchase_units[0].payments.captures[0].amount.value;
receipt.net_amount = receipt.gross_amount;
receipt.processor_fee = "0";
}else{
receipt.gross_amount = orderData.purchase_units[0].payments.captures[0].seller_receivable_breakdown.gross_amount.value;
receipt.net_amount = orderData.purchase_units[0].payments.captures[0].seller_receivable_breakdown.net_amount.value;
receipt.processor_fee = orderData.purchase_units[0].payments.captures[0].seller_receivable_breakdown.paypal_fee.value;
}
//
receipt.purchaser_email = receiptStub.email;
receipt.purchaser_name = receiptStub.name;
receipt.product_name = receiptStub.product_name;
receipt.plugin_category = receiptStub.plugin_category;
//
receipt.mode = processor.mode;
receipt.own_fee = "0";//processor.own_fee;
receipt.processor = processor.processor;
receipt.processor_nameid = processor.nameid;
receipt.is_my_processor = processor.is_my_processor;
receipt.jsontext = JSON.stringify({processor: processor, orderData: orderData});
return receipt;
}
function __setup_paypal(app,self){
// console.log(app)
// console.log(self)
let configs = app.extra.config.configurations.processors;
let domain = app.extra.config.managed_domain;
self._paypal = {
instance: null,
active: null,
all: [],
service_request_url: ""
};
if(configs != undefined){
self._paypal.all = configs;
for(let i=0; i < configs.length; i++){
if(configs[i].json.processor!="paypal")
continue;
if(configs[i].json.active==true){
self._paypal.active = configs[i];
break;
}else if(configs[i].json.active=="true"){
configs[i].json.active = true;
self._paypal.active = configs[i];
break;
}
}
if(self._paypal.active==undefined) return;
// console.log(self._paypal);
self._paypal.service_request_url = domain.Address + ":" + self._paypal.active.json.service_port + "/" + self._paypal.active.json.service_end_point;
}
}
function setupPaypalSubscriptionButton(){
paypal.Buttons({
onApprove: function(data, actions) {
alert('You have successfully subscribed to ' + data.subscriptionID); // Optional message given to subscriber
}
}).render('#paypal-button-container'); // Renders the PayPal button
}// end setupPaypalSubscriptionButton
function setupPaypalButtons(self){
if(paypal==undefined){
//TODO_2: try and reinitialize paypal
console.log("[App]:Error loading PayPal");
}
self.paypal_button = {};
const fundingSources = [
paypal.FUNDING.PAYPAL,
//paypal.FUNDING.CARD
]
for (const fundingSource of fundingSources) {
const paypalButtonsComponent = paypal.Buttons({
fundingSource: fundingSource,
// optional styling for buttons
// https://developer.paypal.com/docs/checkout/standard/customize/buttons-style-guide/
style: {
shape: 'rect',
height: 40
},
// onInit is called when the button first renders
onInit: function(data, actions) {},
onClick: function() {
let process = self.callbacks.button_onClick_callback();
if(process.name==undefined){ process.name = ""; }
if(process.email==undefined){ process.email = ""; }
self.options.process = { ...self.options.process, ...process };
self.options.values = { ...self.options.process, ...process };
self.paypal_button.price = process.amount;
},
// set up the transaction
createOrder: (data, actions) => {
// pass in any options from the v2 orders create call:
// https://developer.paypal.com/api/orders/v2/#orders-create-request-body
const createOrderPayload = {
purchase_units: [{ amount: { value: self.paypal_button.price }}]
}
return actions.order.create(createOrderPayload)
},
// finalize the transaction
onApprove: (data, actions) => {
const captureOrderHandler = (orderData) => {
const payerName = orderData.payer.name.given_name
// console.log(orderData);
let opts = self.options;
var final_amount = orderData.purchase_units[0].payments.captures[0].amount.value;
var mydata = {
"orderData": orderData,
"values": self.options.values,
"options": self.options,
"processor_data": orderData,
"opts": opts
};
self.callbacks.button_onApprove_callback(mydata);
//onCompleteTransaction();
}
return actions.order.capture().then(captureOrderHandler)
},
// handle unrecoverable errors
onError: (err) => {
console.error(err);
},
})
if (paypalButtonsComponent.isEligible()) {
paypalButtonsComponent
.render('#paypal-button-container')
.catch((err) => {
console.error('PayPal Buttons failed to render')
})
} else {
console.log('The funding source is ineligible')
}
}
}// end setupPaypalButtons
function setupPaypalHostedFields(self){
// If this returns false or the card fields aren't visible, see Step #1.
if (paypal.HostedFields.isEligible() == false) {
document.querySelector("#card-form").style = "display: none";// Hides card fields if the merchant isn't eligible
return;
}
// nnnnn
$("#paypal_terms_and_conditions").on("click",function(e){
e.preventDefault();
window.open("https://www.paypal.com/us/legalhub/privacy-full");
})
let orderId;
// Renders card fields
paypal.HostedFields.render({
// Call your server to set up the transaction
createOrder: () => {
// console.log(self);
let pass = self.callbacks.validate_price_callback();
if(pass.pass==false){
return;
}
let price = pass.value; // document.getElementById("card-amount").value;
let priceInt = parseFloat(price);
if(priceInt < 0.50){
// pppp
// TODO: show error message | this should be stopped from the outside
return null;
}
let data = { price: price };
self.options.process.price = price;
//return fetchJsonp(app_config.managed_domain.PaypayServiceUrl + "?" + new URLSearchParams({type:"create_order",data: JSON.stringify(data)}), {
return fetchJsonp(self.pay.service_request_url + "?" + new URLSearchParams({type:"create_order",data: JSON.stringify(data)}), {
method: "get"
})
.then((res) => { return res.json(); })
.then((orderData) => {
if(typeof orderData==='string'){
orderData = JSON.parse(orderData);
}
if(orderData.name!=undefined && orderData.name=="INVALID_REQUEST"){
self.callbacks.error_callback(orderData);
}
orderId = orderData.id; // needed later to complete capture
//console.log(orderData);
return orderData.id;
}).catch((err) => {
console.log(err);
self.callbacks.error_callback(err);
});
},
styles: {
".valid": {
color: "green",
},
".invalid": {
color: "red",
},
},
fields: {
number: {
selector: "#card-number",
placeholder: "4111 1111 1111 1111",
},
cvv: {
selector: "#cvv",
placeholder: "123",
},
expirationDate: {
selector: "#expiration-date",
placeholder: "MM/YY",
},
},
}).then((cardFields) => {
//mmmmm
document.querySelector("#" + self.options.onSubmit.id).addEventListener("click", (event) => {
event.preventDefault();
// console.log(self);
document.getElementById(self.options.onSubmit.id).disabled = true;
setTimeout(() => { document.getElementById(self.options.onSubmit.id).disabled = false; },25000);
let process = self.callbacks.validation_callback(function(innerprocess){
if(innerprocess.pass==false){ return; }
if(innerprocess.name==undefined){ innerprocess.name = ""; }
if(innerprocess.email==undefined){ innerprocess.email = ""; }
self.options.process = { ...self.options.process, ...innerprocess };
self.options.values = { ...self.options.process, ...innerprocess };
self.app.overlay(true, self.options.overlayDelay);
cardFields.submit(cardFieldsSubmit(self))
.then(orderDataResponse(self))
.catch(catchOrderResponseData(self));
});
if(process==undefined) return;
if(process.pass==false){ return; }
if(process.name==undefined){ process.name = ""; }
if(process.email==undefined){ process.email = ""; }
self.options.process = { ...self.options.process, ...process };
self.options.values = { ...self.options.process, ...process };
self.app.overlay(true, self.options.overlayDelay);
cardFields.submit(cardFieldsSubmit(self))
.then(orderDataResponse(self))
.catch(catchOrderResponseData(self));
});
});
}// end setupPaypalHostedFields
function clearPaypalElements(self){
var paypalButtonContainerEl = document.getElementById("paypal-button-container");
if(paypalButtonContainerEl!=null)
paypalButtonContainerEl.innerHTML = "";
}// end clearPaypalElements
function paypal_style(){
return `
<style>
.payment-container {
}
.paypal-button-container {
border-radius: 5px;
background-color: #FFFFFF;
padding: 20px;
max-width: 760px;
width: 100%;
margin: 0 auto;
}
.card_container {
border-radius: 5px;
background-color: #FFFFFF;
max-width: 760px;
width: 100%;
margin: 0 auto;
}
.card_field{
width: 100%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-top: 6px;
margin-bottom: 16px;
resize: vertical;
height:40px;
background:white;
font-size:17px;
color:#3a3a3a;
font-family:helvetica, tahoma, calibri, sans-serif;
}
.card_field_50{
width: 50%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-top: 6px;
margin-bottom: 16px;
resize: vertical;
height:40px;
background:white;
font-size:17px;
color:#3a3a3a;
font-family:helvetica, tahoma, calibri, sans-serif;
}
.card_field_75{
width: 75%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-top: 6px;
margin-bottom: 16px;
resize: vertical;
height:40px;
background:white;
font-size:17px;
color:#3a3a3a;
font-family:helvetica, tahoma, calibri, sans-serif;
}
input[type=text], select, textarea {
width: 100%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-top: 6px;
margin-bottom: 16px;
resize: vertical;
height:40px;
background:white;
font-size:17px;
color:#3a3a3a;
font-family:helvetica, tahoma, calibri, sans-serif;
}
input[type=submit] {
background-color: #4CAF50;
color: white;
padding: 12px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.message_container {
border-radius: 5px;
background:#FFFFFF;
font-size:13px;
font-family:monospace;
padding: 20px;
}
#loading {
width: 100%;
height: 100%;
top: 0;
left: 0;
position: fixed;
display: block;
opacity: 0.7;
background-color: #fff;
z-index: 99;
text-align: center;
}
#loading-image {
position: absolute;
z-index: 15;
top: 50%;
left: 50%;
margin: -100px 0 0 -150px;
}
.spinner {
position: fixed;
top: 50%;
left: 50%;
margin-left: -50px; /* half width of the spinner gif */
margin-top: -50px; /* half height of the spinner gif */
text-align:center;
z-index:1234;
overflow: auto;
width: 100px; /* width of the spinner gif */
height: 102px; /* height of the spinner gif +2px to fix IE8 issue */
}
.button_container {
display: flex;
justify-content: center;
}
.Pbutton:hover {
background-color: powderblue;
}
.Pbutton {
width:229px;
height:49px;
background:lightblue;
border:1px dotted black;
font-size:17px;
color:#3a3a3a;
padding: 12px 20px;
border-radius: 4px;
cursor: pointer;
margin: 0 auto;
}
.btn_small{
width:130px;
height:39px;
background:lightblue;
border:1px dotted black;
font-size:14px;
color:#3a3a3a;
}
.btn_small:hover {
background-color: powderblue;
}
</style>
`;
}// end paypal_style
function orderDataResponse(self){
return function(data){
// (data) => {
// if(DEV) console.log(data);
// https://www2.cradle2careertx.xyz:8443/get_token
return fetchJsonp(self.pay.service_request_url+ "?" + new URLSearchParams({type:"capture_order", orderID: data.orderId}), {
method: "get",
}).then((res) => {
return res.json();
}).catch((err) => {
console.log(err);
}).then((orderData) => {
// if(DEV) console.log(orderData);
let opts = self.options;
var final_amount = orderData.purchase_units[0].payments.captures[0].amount.value;
var email = opts.email;// document.getElementById("card-email").value;
var name = opts.name; // document.getElementById("card-holder-name").value;
if(email==undefined || email==null || email==""){email = "_none_";}
if(name==undefined || name==null || name==""){name = "_none_";}
var mydata = {
"orderData": orderData,
"values": self.options.values,
"options": self.options,
"processor_data": orderData,
"opts": opts
};
// if(DEV) console.log(r);
//ModalHandler();
// Two cases to handle:
// (1) Other non-recoverable errors -> Show a failure message
// (2) Successful transaction -> Show confirmation or thank you
// This example reads a v2/checkout/orders capture response, propagated from the server
// You could use a different API or structure for your 'orderData'
const errorDetail = Array.isArray(orderData.details) && orderData.details[0];
if (errorDetail) {
// TODO: throw user friendly error message
var msg = opts.charge_failure_message;
if (errorDetail.description)
msg += "\n\n" + errorDetail.description;
if (orderData.debug_id) msg += " (" + orderData.debug_id + ")";
opts.error_callback(orderData,errorDetail);
return msg; // alert(msg); // Show a failure message
}
clearPaypalElements(self)
self.callbacks.success_callback(mydata);
let success_content = self.callbacks.success_content(mydata);
// TODO: Move this out of afspayments and into client.
const myModalAlternative = new bootstrap.Modal("#modal_donation_dialog_success", {});
$("#dialog_container_success").empty();
$("#dialog_container_success").append(success_content);
setTimeout(function(){
// nnnn
myModalAlternative.show();
self.app.overlay(false);
document.getElementById(self.options.onSubmit.id).disabled = false;
},2000);
}).catch((err) => {
console.error(err);
// console.log(err);
});
} // end return
}
function cardFieldsSubmit(self){
// mmmmm
return {
// Cardholder's first and last name
cardholderName: self.options.process.name , //document.getElementById("card-holder-name").value,
// Billing Address
billingAddress: {
// Street address, line 1
streetAddress: (self.options.billingAddressEnabled) ? document.getElementById("card-billing-address-street").value : "",
// Street address, line 2 (Ex: Unit, Apartment, etc.)
extendedAddress: (self.options.billingAddressEnabled) ? document.getElementById("card-billing-address-unit").value : "",
// State
region: (self.options.billingAddressEnabled) ? document.getElementById("card-billing-address-state").value : "",
// City
locality: (self.options.billingAddressEnabled) ? document.getElementById("card-billing-address-city").value : "",
// Postal Code
postalCode: document.getElementById("card-billing-address-zip").value,
// Country Code
countryCodeAlpha2: "US" // document.getElementById("card-billing-address-country").value,
}
}
}
function catchOrderResponseData(self){
return function(err){
var status = document.getElementById("payment-status-message-title");
if(status){
status.innerHTML = self.options.paypal_error_message;
status.style = "color:red";
// ccccc
}
self.callbacks.error_callback(err);
self.app.overlay(false);
console.log(err);//alert("Payment could not be captured! " + JSON.stringify(err));
};
}
function payaplCheckOutHtmlElement(paypal_style,self){
let showpaypalbutton = "";
if(self.options.showPaypalButton){
showpaypalbutton = `
<div class="row">
<div class="">
<div id="paypal-button-container" class="paypal-button-container"></div>
</div>
</div>
`;
}
let or = "";
if(self.options.showPaypalForm && self.options.showPaypalButton){
or = `
<div class="row justify-content-center">
<div class="">
<div><p style="text-align: center;">or</p></div>
</div>
</div>
`;
}
let showpaypalform = "";
if(self.options.showPaypalForm){
showpaypalform = `
<div class="row justify-content-center">
<div class="">
<div class="card_container">
<form id="card-form">
<label for="card-number">Card Number</label>
<div id="card-number" class="card_field"></div>
<div style="display: flex; flex-direction: row;">
<div>
<label for="expiration-date">Expiration Date</label>
<div id="expiration-date" class="card_field"></div>
</div>
<div style="margin-left: 10px;">
<label for="cvv">CVV</label>
<div id="cvv" class="card_field"></div>
</div>
</div>
${getBillingAddressNameHtml(self)}
${getBillingAddressHtml(self)}
<div>
<input
type="text"
id="card-billing-address-zip"
name="card-billing-address-zip"
autocomplete="off"
placeholder="zip / postal code"
/>
</div>
<!--
<div>
<input
type="text"
id="card-billing-address-country"
name="card-billing-address-country"
autocomplete="off"
placeholder="country code"
/>
-->
</div>
<br />
${self.options.onSubmit.htmlButton}
${self.options.termsAgreementText}
</form>
</div>
</div>
</div>
`;
}
return `
${paypal_style()}
<div id="payment-container" class="payment-container">
<div class="">
<div><p id="payment-status-message-title"></p></div>
${showpaypalbutton}
${or}
${showpaypalform}
</div><!--Container-->
</div><!--payment-container-->
`;
}
function setupOptions(self,obj){
self.container_id = obj.container_id;
self.callbacks = {};
self.contents = {};
// options
if(obj.options==undefined){
obj.options = {};
}
obj.options.process = {};
if(obj.options.delay==undefined){
obj.options.delay = 500;
}
if(obj.options.container_id==undefined){
obj.options.container_id = "";
}
if(obj.options.appendNow==undefined){
obj.options.appendNow = true;
}
if(obj.options.showPaypalForm==undefined){
obj.options.showPaypalForm = true;
}
if(obj.options.showPaypalButton==undefined){
obj.options.showPaypalButton = true;
}
if(obj.options.paypal_error_message==undefined){
obj.options.paypal_error_message = "Sorry there was an error process your payment.";
}
if(obj.options.submit_button==undefined){
obj.options.submit_button = {id:"defualt_submit_button_id",label:"Submit"};
}
if(obj.options.onSubmit==undefined){
obj.options.onSubmit = {
id:"defualt_submit_button_id",
label:"Submit",
showButton:true
};
}
if(obj.options.termsAgreementText==undefined){
obj.options.termsAgreementText = `<div class="mt-3 d-flex justify-content-center">By clicking Donate you agree to the <a id="paypal_terms_and_conditions" href="#">Terms & Conditions</a></p></div>`;
}
if(obj.options.onSubmit.showButton==undefined || obj.options.onSubmit.showButton==true){
obj.options.onSubmit.htmlButton = `<button value="submit" id="${obj.options.onSubmit.id}" style="width: 100%; color: white" class="btn btn-success ${obj.options.submit_button.className}"><strong>${obj.options.onSubmit.label}</strong></button>`;
}else{
obj.options.onSubmit.htmlButton = "";
}
if(obj.options.overlayDelay==undefined){
obj.options.overlayDelay = 20000;
}
if(obj.options.billingAddressEnabled==undefined){
obj.options.billingAddressEnabled = false;
}
if(obj.options.billingAddressNameEnabled==undefined){
obj.options.billingAddressNameEnabled = false;
}
if(obj.options.no_reply_subject==undefined){
obj.options.no_reply_subject = "";
}
self.options = obj.options;
// contents
if(obj.success_content==undefined){
obj.success_content = function(mydata){ return ""; };
}
self.contents.success_content = obj.success_content;
// callbacks
if(obj.success_callback==undefined){
obj.success_callback = function(){};
}
self.callbacks.success_callback = obj.success_callback;
if(obj.error_callback==undefined){
obj.error_callback = function(erre){};
}
self.callbacks.error_callback = obj.error_callback;
if(obj.validation_callback==undefined){
console.log("validation_callback callbck not set");
obj.validation_callback = function(){return {pass:true}}
}
self.callbacks.validation_callback = obj.validation_callback;
if(obj.validate_price_callback==undefined){
console.log("validate_price_callback callbck not set");
obj.validation_callback = function(){return {pass:true}}
}
self.callbacks.validate_price_callback = obj.validate_price_callback;
if(obj.success_content==undefined){
console.log("success_content callbck not set");
obj.success_content = function(){return {pass:true}}
}
self.callbacks.success_content = obj.success_content;
if(obj.button_onApprove_callback==undefined){
obj.button_onApprove_callback = function(){};
}
self.callbacks.button_onApprove_callback = obj.button_onApprove_callback;
if(obj.button_onClick_callback==undefined){
obj.button_onClick_callback = function(){};
}
self.callbacks.button_onClick_callback = obj.button_onClick_callback;
}
function getBillingAddressNameHtml(self){
var name = "";
if(self.options.billingAddressNameEnabled){
name = `
<label for="card-holder-name">Name on Card</label>
<input
type="text"
id="card-holder-name"
name="card-holder-name"
autocomplete="off"
placeholder="card holder name"
/>
`;
}
return name;
}
function getBillingAddressHtml(self){
var billingAddressHtml = "";
if(self.options.billingAddressEnabled){
billingAddressHtml = `
<div>
<label for="card-billing-address-street">Billing Address</label>
<input
type="text"
id="card-billing-address-street"
name="card-billing-address-street"
autocomplete="off"
placeholder="street address"
/>
</div>
<div>
<label for="card-billing-address-unit">&nbsp;</label>
<input
type="text"
id="card-billing-address-unit"
name="card-billing-address-unit"
autocomplete="off"
placeholder="unit"
/>
</div>
<div>
<input
type="text"
id="card-billing-address-city"
name="card-billing-address-city"
autocomplete="off"
placeholder="city"
/>
</div>
<div>
<input
type="text"
id="card-billing-address-state"
name="card-billing-address-state"
autocomplete="off"
placeholder="state"
/>
</div>
`;
}
return billingAddressHtml;
}// end getBillingAddressHtml
return PaymentsPayPal;
}
function initpayment_stripe(){
class PaymentsStripe {
constructor(processor_config, directPaymentInstance, managed_domain) {
let self = this;
self.directPaymentInstance = directPaymentInstance;
self.processor = processor_config;
self.managed_domain = managed_domain;
self.service_request_url = "";
self.service_request_post_url = "";
self.service_request_get_url = "";
let url = self.managed_domain.Address + ":" + self.processor.json.service_port + "/" + self.processor.json.service_end_point;
self.service_request_url = url;
self.service_request_get_url = url;
self.service_request_post_url = self.managed_domain.Address + ":" + self.processor.json.service_port;
}
getProcessorConfiguration(){
return this.processor;
}
getSubscriptions(props,cb){
_getSubscriptions(props,cb,this);
}
createMembershipTier(options,cb){
_createMembershipTier(options,cb,this);
}
createCustomer(props,cb,directPayment){
_createCustomer(props,cb,directPayment,this);
}
createSubscription(props,cb,directPayment){
_createSubscription(props,cb,directPayment,this);
}
setupView(data,selection,app,onStartCB,onFinishCB) {
return _stripe_view(data,selection,app,onStartCB,onFinishCB,this);
}
startMemebership(stripe,obj,data,selection,app,cb){
_startMemebership(stripe,obj,data,selection,app,cb,this);
}
initialize_payment_details(stripe,data,selection,app) {
return _initialize_payment_details(stripe,data,selection,app,this);
}
initializeSubscription(props){
_initializeSubscription(props,this);
}
check(cb) {
_check_stripe_service(cb, this);
}
account() {
_stripe_account(this);
}
cancel() {
_stripe_cancel(this);
}
subscribe() {
_stripe_subscribe(this);
}
prices() {
_stripe_prices(this);
}
standalone(props,cb){
_stripe_standalone_payment(props,cb,this);
}
// options,cbStart,cbSuccess,cbBackEndError,cbStripeError,self
singleCharge(options,cbStart,cbSuccess,cbBackEndError,cbStripeError){
_stripe_single_charge_payment_intent(options,cbStart,cbSuccess,cbBackEndError,cbStripeError,this);
}
}
async function _initializeSubscription(){
}
async function _check_stripe_service(cb,self){
let data = {checking:true};
console.log(self.service_request_url)
fetchJsonp(self.service_request_url + "?" + new URLSearchParams({type:"check",data: JSON.stringify(data)}), {
method: "get"
})
.then(resp => resp.json())
.then((response) => {
console.log(response);
cb(response);
}).catch((err) => {
console.error(err);
cb(false,err);
});
}
function _createMembershipTier(options,cb,self){
let subscriptions = self.subscription_data;
// console.log(subscriptions);
for (let i = 0; i < subscriptions.prices.length; i++) {
// const json_data = app.extra.config.configurations.access_member[0].json;
let json_data = {};
const index = i;
const price = subscriptions.prices[index];
const unitprice = price.unit_amount/100;
if(price.lookup_key==options.lookup_key){
$(options.label_price).text(`${unitprice}`);
$(options.label_name).text(price.product.name);
$(options.onclick).on("click",function(e){
e.preventDefault();
// console.log(price);
json_data.label_price = price.unit_amount/100
json_data.label = price.product.name;
json_data.transactions = {
stripe: {
price: price
}
};
// json_data.group = app.extra.current.group;
// app.extra.current.member.selection.json_data.price = price;
// app.extra.current.member.selection.membership = 3;
// app.extra.current.member.selection = {
// json_data: json_data,
// price: price,
// membership: 3
// };
if(cb!=undefined) cb(json_data);
// console.log(price);
// console.log(app.extra.current.member.selection)
// app.extra.views.init.render("checkout");
});
}
}
}
async function _getSubscriptions(props,cb,self){
fetchJsonp(self.service_request_url + "?" + new URLSearchParams({type:"config",data: JSON.stringify(props)}), {
method: 'get',
headers: {
'Content-Type': 'application/json',
}
})
.then((response) => response.json())
.then((data) => {
self.subscription_data = data;
cb(data);
data.prices.forEach((price) => {});
})
.catch((error) => {
console.error('Error:', error);
cb(error);
});
}
async function _createCustomer(props,cb,directPayment,self){
// let data = {
// email: props.email,
// reference_num: props.reference_num,
// payment_intent: props.payment_intent
// }
console.log(directPayment);
props.processor = directPayment.configurations.processor.json.nameid;
console.log(props);
console.log(directPayment);
directPayment.appManager.apicall("/v1/payments/stripe_create_customer",{
method: 'POST',
body: JSON.stringify(props)
},function(resp){
console.log(resp);
if(cb!=undefined) cb(resp);
});
// fetchJsonp(self.service_request_url + "?" + new URLSearchParams({type:"create-customer",data: JSON.stringify(props)}), {
// method: 'get',
// headers: {'Content-Type': 'application/json'}
// })
// .then(resp => resp.json())
// .then((customer) => {
// cb(customer);
// }).catch((err) => {
// console.log(err);
// cb(false,err);
// });
}
async function _createSubscription(props,cb,directPayment,self){
// console.log(props);
// console.log(directPayment);
let data = {
price_id: props.json_data.transactions.stripe.price.id,
customer_id: props.json_data.transactions.stripe.customer.id,
processor: directPayment.processor.processor.json.nameid,
// reference_num: props.reference_num
}
directPayment.appManager.apicall("/v1/payments/stripe_create_subscription",{
method: 'POST',
body: JSON.stringify(data)
},function(resp){
console.log(resp);
directPayment._current_subscription = resp["response"]["subscription"];
if(cb!=undefined) cb(resp["response"]);
});
// fetchJsonp(self.service_request_url + "?" + new URLSearchParams({type:"create-subscription",data: JSON.stringify(data)}), {
// method: 'get',
// headers: {'Content-Type': 'application/json'}
// })
// .then((response) => response.json())
// .then((data) => {
// cb(data);
// })
// .catch((error) => {
// console.error('Error:', error);
// cb(error);
// });
}
// TODO_1: Remove depedency for app
function _stripe_view(data,selection,app,onStartCB,onFinishCB,self){
// let app = self.paymentservice.app;
let view = app.factory.view();
self.view = view;
view.newSubView({
id: "payment_details",
init: true,
body: app.extra.config.html.stripe_subscription_payment_details,
listener: function(){
// nnnn
console.log(self);
const publishableKey = self.processor.json.client_id;
const stripe = Stripe(publishableKey);
let obj = self.initialize_payment_details(stripe,data,selection,app);
setTimeout(() => {
$("#stripe_start_membership_id").css("display","block");
$("#stripe_start_membership_id").on("click",function(e){
e.preventDefault();
// console.log(obj);
if(onStartCB!=undefined && onStartCB!=null) onStartCB(obj);
self.startMemebership(stripe,obj,data,selection,app,onFinishCB);
});
},1000);
}
});
return view;
}
async function _startMemebership(stripe,obj,data,selection,app,cb,self){
// const nameInput = document.getElementById('name');
console.log("*******************************************");
console.log(data);
const clientSecret = data.client_secret;
// Create payment method and confirm payment intent.
stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: obj.cardElement,
billing_details: {
name: selection.firstname + " " + selection.lastname,
},
}
}).then((result) => {
if(result.error) {
// setMessage(`Payment failed: ${result.error.message}`);
cb(result.error);
} else {
// Redirect the customer to their account page
// setMessage('Success! Redirecting to your account.');
// window.location.href = '/account.html';
let data2 = {
payment: result.paymentIntent.payment_method,
processor: self.directPaymentInstance.processor.processor.json.nameid
}
// console.log("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
// console.log(result);
// console.log(data);
// console.log(data2);
// console.log(selection);
// console.log(app);
// console.log(self);
// give some time for payment to post
setTimeout(() => {
self.directPaymentInstance.appManager.apicall("/v1/payments/stripe_check_charge",{
method: 'POST',
body: JSON.stringify(data2)
},function(resp){
// console.log(resp);
let card_brand = resp["response"]["card"]["brand"];
let card_last4 = resp["response"]["card"]["last4"];
result["card_brand"] = card_brand;
result["card_last4"] = card_last4;
if(cb!=undefined) cb(result, self.directPaymentInstance._current_subscription, selection);
});
},3000);
}
});
}
function _initialize_payment_details(stripe,data,selection,app,self){
const appearance = {
theme: 'flat',
variables: { colorPrimaryText: '#262626' }
};
// console.log("*******************************************");
// console.log(data);
// console.log(data);
// console.log(selection);
// console.log(self);
const elements = stripe.elements({clientSecret: data.client_secret, appearance:appearance});
const cardElement = elements.create('card');
const addressElementsOptions = { mode: 'billing' };
const addressElement = elements.create('address', addressElementsOptions);
addressElement.mount('#address-element');
cardElement.mount('#payment-element');
return {cardElement,stripe}
}
function _stripe_register(self){
document.addEventListener('DOMContentLoaded', async () => {
const signupForm = document.querySelector('#signup-form');
if (signupForm) {
signupForm.addEventListener('submit', async (e) => {
e.preventDefault();
// Grab reference to the emailInput. The email address
// entered will be passed to the server and used to create
// a customer. Email addresses do NOT uniquely identify
// customers in Stripe.
const emailInput = document.querySelector('#email');
//self._paypal.service_request_url = domain.Address + ":" + self._paypal.active.json.service_port + "/" + self._paypal.active.json.service_end_point;
let data = {
"sender_batch_header": {
"sender_batch_id": "Payouts_2020_100007",
"email_subject": "You have a payout!",
"email_message": "You have received a payout! Thanks for using our service!"
},
"items": [
{
"recipient_type": "EMAIL",
"amount": { "value": "9.87", "currency": "USD" },
"note": "Thanks for your patronage!",
"sender_item_id": "201403140001",
"receiver": "receiver@example.com",
"recipient_wallet": "RECIPIENT_SELECTED"
}
]
};
// create_webhook
fetchJsonp(self.service_request_url + "?" + new URLSearchParams({type:"payout",data: JSON.stringify(data)}), {
method: "get"
})
.then((response) => {
}).catch((err) => {
console.log(err);
});
// Create a customer. This will also set a cookie on the server
// to simulate having a logged in user.
const {customer} = await fetch('/create-customer', {
method: 'post',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: emailInput.value,
}),
}).then(r => {
console.log(r.json());
return r.json();
});
// Redirect to the pricing page.
// window.location.href = '/prices.html';
self.view.render("prices");
});
} else {
alert("No sign up form with ID `signup-form` found on the page.");
}
});
}
function _stripe_account(self){
document.addEventListener('DOMContentLoaded', async () => {
// Fetch the list of subscriptions for this customer.
const {subscriptions} = await fetch('/subscriptions').then((r) => r.json());
// Construct and display each subscription, its status, last4 of the card
// used, and the current period end.
const subscriptionsDiv = document.querySelector('#subscriptions');
subscriptionsDiv.innerHTML = subscriptions.data.map((subscription) => {
let last4 = subscription.default_payment_method?.card?.last4 || '';
return `
<hr>
<h4>
<a href="https://dashboard.stripe.com/test/subscriptions/${subscription.id}">
${subscription.id}
</a>
</h4>
<p>
Status: ${subscription.status}
</p>
<p>
Card last4: ${last4}
</p>
<small>If the last4 is blank, ensure webhooks are being handled. The default payment method is set in the webhook handler.</small>
<p>
Current period end: ${new Date(subscription.current_period_end * 1000)}
</p>
<!--<a href="change-payment-method.html?subscription=${subscription.id}"> Update payment method </a><br />
<a href="change-plan.html?subscription=${subscription.id}"> Change plan </a><br /> -->
<a href="cancel.html?subscription=${subscription.id}"> Cancel </a><br />
`;
}).join('<br />');
});
}
function _stripe_cancel(self){
document.addEventListener('DOMContentLoaded', async () => {
// Fetch the ID of the subscription from the query string
// params.
const params = new URLSearchParams(window.location.search);
const subscriptionId = params.get('subscription');
// When the cancel button is clicked, send an AJAX request
// to our server to cancel the subscription.
const cancelBtn = document.querySelector('#cancel-btn');
cancelBtn.addEventListener('click', async (e) => {
e.preventDefault();
setMessage("Cancelling subscription...");
const {subscription} = await fetch('/cancel-subscription', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
subscriptionId
}),
})
.then((response) => response.json())
// Display the status of the subscription after attempting to
// cancel.
setMessage(`Subscription status: ${subscription.status}`);
setMessage(`Redirecting back to account in 7s.`);
// Redirect to the account page.
setTimeout(() => {
window.location.href = "account.html";
}, 7 * 1000);
});
const setMessage = (message) => {
const messagesDiv = document.querySelector('#messages');
messagesDiv.innerHTML += "<br>" + message;
}
});
}
function _stripe_subscribe(self){
// helper method for displaying a status message.
const setMessage = (message) => {
const messageDiv = document.querySelector('#messages');
messageDiv.innerHTML += "<br>" + message;
}
// Fetch public key and initialize Stripe.
let stripe, cardElement;
let data = {};
fetchJsonp(self.service_request_url + "?" + new URLSearchParams({type:"config",data: JSON.stringify(data)}), {
method: "get"
})
.then((resp) => resp.json())
.then((resp) => {
stripe = Stripe(resp.publishableKey);
const elements = stripe.elements();
cardElement = elements.create('card');
cardElement.mount('#card-element');
}).catch((err) => {
console.log(err);
});
// fetch('/config')
// .then((resp) => resp.json())
// .then((resp) => {
// stripe = Stripe(resp.publishableKey);
// const elements = stripe.elements();
// cardElement = elements.create('card');
// cardElement.mount('#card-element');
// });
// Extract the client secret query string argument. This is
// required to confirm the payment intent from the front-end.
const subscriptionId = window.sessionStorage.getItem('subscriptionId');
const clientSecret = window.sessionStorage.getItem('clientSecret');
// This sample only supports a Subscription with payment
// upfront. If you offer a trial on your subscription, then
// instead of confirming the subscription's latest_invoice's
// payment_intent. You'll use stripe.confirmCardSetup to confirm
// the subscription's pending_setup_intent.
// See https://stripe.com/docs/billing/subscriptions/trials
// Payment info collection and confirmation
// When the submit button is pressed, attempt to confirm the payment intent
// with the information input into the card element form.
// - handle payment errors by displaying an alert. The customer can update
// the payment information and try again
// - Stripe Elements automatically handles next actions like 3DSecure that are required for SCA
// - Complete the subscription flow when the payment succeeds
const form = document.querySelector('#subscribe-form');
form.addEventListener('submit', async (e) => {
e.preventDefault();
const nameInput = document.getElementById('name');
// Create payment method and confirm payment intent.
stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: cardElement,
billing_details: {
name: nameInput.value,
},
}
}).then((result) => {
if(result.error) {
setMessage(`Payment failed: ${result.error.message}`);
} else {
// Redirect the customer to their account page
setMessage('Success! Redirecting to your account.');
window.location.href = '/account.html';
}
});
});
}
async function _stripe_single_charge_payment_intent(options,cbStart,cbSuccess,cbBackEndError,cbStripeError,self){
let data = {
// customer: options.customer,
// mail_handlers: options.mail_handlers
};
fetchJsonp(self.service_request_url + "?" + new URLSearchParams({type:"signle-create-payment-intent",data: JSON.stringify(data)}), {
method: "get"
})
.then((resp) => resp.json())
.then(async (resp) => {
let clientSecret = resp.clientSecret;
if (resp.error) {
console.log(resp);
console.log(cbBackEndError);
if(cbBackEndError!=undefined && cbBackEndError!=null) cbBackEndError(resp);
return;
}
if(options.name==undefined) options.name = "";
if(options.email==undefined) options.email = "";
cbStart(resp.paymentIntent, async function(){
// Confirm the card payment given the clientSecret
// from the payment intent that was just created on
// the server.
const {error: stripeError, paymentIntent} = await options.stripe.confirmCardPayment(
clientSecret,
{
payment_method: {
card: options.card,
billing_details: {
name: options.name,
phone: "713-777-5555",
_member_reference_num: options._member_reference_num
},
},
metadata: {
}
}
);
if (stripeError) {
console.log(stripeError);
if(cbStripeError!=undefined && cbStripeError!=null) cbStripeError(stripeError);
return;
}
cbSuccess(paymentIntent);
});
}).catch((err) => {
console.error(err);
// cb(null,null);
});
}
async function _stripe_standalone_payment(props,cb,self){
let data = {};
let stripe = null;
fetchJsonp(self.service_request_url + "?" + new URLSearchParams({type:"keys",data: JSON.stringify(data)}), {
method: "get"
})
.then((resp) => resp.json())
.then((resp) => {
// stripe = Stripe(resp.publishableKey);
stripe = Stripe(resp.keys.client_id);
// console.log(resp);
cb(stripe);
}).catch((err) => {
console.log(err);
cb(null,null);
});
}
return PaymentsStripe;
}
function initemail_handler(){
class EmailHandler {
// 77777
constructor(id,handlers,domain_settings,managed_domain){
this.id = id;
this.domain_settings = domain_settings;
this.managed_domain = managed_domain;
this.handlers = handlers;
this.handler = this.getHandler(id);
}
getHandlers(){
return this.handlers;
}
getHandler(id){
let self = this;
let handler = null;
for (const key in self.handlers) {
if(key==id){
handler = self.handlers[id];
break;
}
}
return handler;
}
setupVariables(emails,variables){
const self = this;
let managed_domain = self.managed_domain;
let domain_settings = self.domain_settings;
for (const key in self.handler.handlers) {
let handlerClone = structuredClone(self.handler.handlers[key]);
let schemaVars = structuredClone(handlerClone.variables.schema);
let systemVars = structuredClone(SetupSystemVariables(handlerClone, domain_settings, managed_domain));
handlerClone.variables.schema = [schemaVars];
handlerClone.variables.system = [systemVars];
handlerClone.variables.client = [variables];
if(handlerClone.alert==false){
if(typeof emails === "string"){ emails = [emails]; }
handlerClone["emails"] = emails;
}
self.handler.handlers[key] = handlerClone;
}
}
}
return EmailHandler;
}
// https://github.com/camsong/fetch-jsonp
function initializeJsonp(exports, module) {
'use strict';
var defaultOptions = {
// TODO: fetch-jsonp - original value was 5 seconds 5000ms
timeout: 30000,
jsonpCallback: 'callback',
jsonpCallbackFunction: null
};
function generateCallbackFunction() {
return 'jsonp_' + Date.now() + '_' + Math.ceil(Math.random() * 100000);
}
function clearFunction(functionName) {
// IE8 throws an exception when you try to delete a property on window
// http://stackoverflow.com/a/1824228/751089
try {
delete window[functionName];
} catch (e) {
window[functionName] = undefined;
}
}
function removeScript(scriptId) {
var script = document.getElementById(scriptId);
if (script) {
document.getElementsByTagName('head')[0].removeChild(script);
}
}
function fetchJsonp(_url) {
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
// to avoid param reassign
var url = _url;
var timeout = options.timeout || defaultOptions.timeout;
var jsonpCallback = options.jsonpCallback || defaultOptions.jsonpCallback;
var timeoutId = undefined;
return new Promise(function (resolve, reject) {
var callbackFunction = options.jsonpCallbackFunction || generateCallbackFunction();
var scriptId = jsonpCallback + '_' + callbackFunction;
window[callbackFunction] = function (response) {
resolve({
ok: true,
// keep consistent with fetch API
json: function json() {
return Promise.resolve(response);
}
});
if (timeoutId) clearTimeout(timeoutId);
removeScript(scriptId);
clearFunction(callbackFunction);
};
// Check if the user set their own params, and if not add a ? to start a list of params
url += url.indexOf('?') === -1 ? '?' : '&';
var jsonpScript = document.createElement('script');
jsonpScript.setAttribute('src', '' + url + jsonpCallback + '=' + callbackFunction);
if (options.charset) {
jsonpScript.setAttribute('charset', options.charset);
}
if (options.nonce) {
jsonpScript.setAttribute('nonce', options.nonce);
}
if (options.referrerPolicy) {
jsonpScript.setAttribute('referrerPolicy', options.referrerPolicy);
}
jsonpScript.id = scriptId;
document.getElementsByTagName('head')[0].appendChild(jsonpScript);
timeoutId = setTimeout(function () {
reject(new Error('JSONP request to ' + _url + ' timed out'));
clearFunction(callbackFunction);
removeScript(scriptId);
window[callbackFunction] = function () {
clearFunction(callbackFunction);
};
}, timeout);
// Caught if got 404/500
jsonpScript.onerror = function () {
reject(new Error('JSONP request to ' + _url + ' failed'));
clearFunction(callbackFunction);
removeScript(scriptId);
if (timeoutId) clearTimeout(timeoutId);
};
});
}
// export as global function
/*
let local;
if (typeof global !== 'undefined') {
local = global;
} else if (typeof self !== 'undefined') {
local = self;
} else {
try {
local = Function('return this')();
} catch (e) {
throw new Error('polyfill failed because global object is unavailable in this environment');
}
}
local.fetchJsonp = fetchJsonp;
*/
return fetchJsonp;
}
function _make(props,self,cb){
console.log(self);
self.stripeProcessor.standalone(props,function(stripe){
// console.log(stripe);
const elements = stripe.elements();
const card = elements.create('card');
card.mount(props.cardElementId);
if(props.submitId==undefined){console.log("Please provide on submit button id for payment component");}
// console.log(props.submitId.split("#")[1]);
let button = document.getElementById(props.submitId.split("#")[1]);
button.replaceWith(button.cloneNode(true));
// console.log(button);
document.querySelector(props.submitId).addEventListener('click', async (e) => {
e.preventDefault();
let properties = {success:true};
if(props.validate!=undefined && props.validate!=null){
properties = props.validate();
}
// console.log(properties);
properties.stripe = stripe;
properties.card = card;
properties.mail_handlers = properties.mail_handlers;
if(properties.success==false){
return;
}
//options,cbStart,cbSuccess,cbBackEndError,cbStripeError,self
self.stripeProcessor.singleCharge(properties,
function(payment_intent, cbContinue){
// console.log(payment_intent);
// 77777
self.stripeProcessor.directPaymentInstance.saveEmailHandlersForPayment(payment_intent,function(){
setTimeout(() => {
// mm7777
self.stripeProcessor.createCustomer({
reference_num: properties.customer[0],
email: properties.customer[1],
payment_intent: payment_intent,
// mail_handlers: properties.mail_handlers
},function(customer){
if(properties.callback!=undefined && properties.callback!=null && typeof properties.callback=="function"){
properties.callback(customer);
}
cbContinue();
}, self);
},1000);
});
},function(paymentIntent){
console.log(1);
if(props.success!=undefined && props.success!=null){
console.log(2);
properties = props.success(paymentIntent);
}
},function(backendError){
console.log(props);
if(props.error!=undefined && props.error!=null){
properties = props.error(backendError, null);
}
},function(paymentIntent){
console.log(paymentIntent);
if(props.error!=undefined && props.error!=null){
properties = props.error(null, paymentIntent);
}
});
});
});
}
// TODO_3: Do variable replace on server side
function SetupSystemVariables(handlerClone, domain_settings, managed_domain, email){
// 77777
let variables = [];
let settings = domain_settings.json;
// -subscribe_button_link
variables.push({
name: "subscribe_button_link",
value: managed_domain.Address
});
// -mysocial_link_threads
variables.push({
name: "mysocial_link_threads",
value: settings.social_media_links.threads
});
// -mysocial_link_twitch
variables.push({
name: "mysocial_link_twitch",
value: settings.social_media_links.twitch
});
// -mysocial_link_youtube
variables.push({
name: "mysocial_link_youtube",
value: settings.social_media_links.youtube
});
// -mysocial_link_discord
variables.push({
name: "mysocial_link_discord",
value: settings.social_media_links.discord
});
// -mysocial_link_pinterest
variables.push({
name: "mysocial_link_pinterest",
value: settings.social_media_links.pinterest
});
// -mysocial_link_tiktok
variables.push({
name: "mysocial_link_tiktok",
value: settings.social_media_links.tiktok
});
// -mysocial_link_linkedin
variables.push({
name: "mysocial_link_linkedin",
value: settings.social_media_links.linkedin
});
// -mysocial_link_instagram
variables.push({
name: "mysocial_link_instagram",
value: settings.social_media_links.instagram
});
// -mysocial_link_twitter
variables.push({
name: "mysocial_link_twitter",
value: settings.social_media_links.twitter
});
// -mysocial_link_facebook
variables.push({
name: "mysocial_link_facebook",
value: settings.social_media_links.facebook
});
// -mycopyright_short
variables.push({
name: "mycopyright_short",
value: settings.company.copyright_short
});
// -mycopyright_long
variables.push({
name: "mycopyright_long",
value: settings.company.copyright_long
});
// -mycompany_name
variables.push({
name: "mycompany_name",
value: settings.company.name
});
// -mycompany_address
variables.push({
name: "mycompany_address",
value: settings.company.address
});
// -mycompany_phone
variables.push({
name: "mycompany_phone",
value: settings.company.phone
});
// -mybrand_logo1
let logo1Url = settings.brand.logos.logo1;
variables.push({
name: "mybrand_logo1",
value: (logo1Url==undefined || logo1Url==null) ? "" : logo1Url.url
});
// -mybrand_logo1
let logo2Url = settings.brand.logos.logo2;
variables.push({
name: "mybrand_logo2",
value: (logo2Url==undefined || logo2Url==null) ? "" : logo2Url.url
});
// -mybrand_logo1
let logo3Url = settings.brand.logos.logo3;
variables.push({
name: "mybrand_logo3",
value: (logo3Url==undefined || logo3Url==null) ? "" : logo3Url.url
});
// -mybrand_color_1
variables.push({
name: "mybrand_color_1",
value: settings.brand.colors.primary_color_1
// value: app.extra.instances.domain.getDashboardSettings().json.brand.colors.primary_color_1
});
// -mybrand_color_2
variables.push({
name: "mybrand_color_2",
value: settings.brand.colors.primary_color_2
});
// -mybrand_color_3
variables.push({
name: "mybrand_color_3",
value: settings.brand.colors.primary_color_3
});
// -mybrand_favicon1
variables.push({
name: "mybrand_favicon1",
value: settings.brand.favicons.favicon1
});
// -mydomain
variables.push({
name: "domain",
value: managed_domain.Address
});
// -domain_dashboard
variables.push({
name: "domain_dashboard",
value: managed_domain.Address + "/portal/admin"
});
// -myheader_image_url
variables.push({
name: "myheader_image_url",
value: managed_domain.Address + "/assets/logo.png"
});
// -logo
variables.push({
name: "logo",
value: managed_domain.Address + "/assets/logo.png"
});
// -logo2
variables.push({
name: "logo2",
value: managed_domain.Address + "/assets/logo2.png"
});
// -logo3
variables.push({
name: "logo3",
value: managed_domain.Address + "/assets/logo3.png"
});
// yyyyy
variables.push({
"name": "dollar_amount",
"value": "",
"type": "payments"
});
variables.push({
"name": "card_type",
"value": "",
"type": "payments"
});
variables.push({
"name": "last4",
"value": "",
"type": "payments"
});
variables.push({
"name": "currency",
"value": "",
"type": "payments"
});
variables.push({
"name": "receipt_url",
"value": "",
"type": "payments"
});
if(email!=undefined){
// from_email
variables.push({
name: "email_from",
value: email.from
});
// email_subject
variables.push({
name: "email_subject",
value: email.subject
});
if(email.integration!=undefined){
// email_domain
variables.push({
name: "email_domain",
value: email.integration.domain
});
// email_server
variables.push({
name: "email_server",
value: email.integration.server
});
}
}
for (let i = 0; i < variables.length; i++) {
const element = variables[i];
if(variables[i].value==undefined) variables[i].value = "";
}
return variables;
}
function __runPaypal(opts,self){
// console.log(opts);
let cb = undefined;
self.dp.appManager.apicall("/v1/payments/paypal/orders",{
method: 'POST',
body: JSON.stringify({
cart: [
{
id: "YOUR_PRODUCT_ID",
quantity: "YOUR_PRODUCT_QUANTITY",
},
],
})
},function(resp){
resp = JSON.parse(resp);
console.log(resp);
if(cb!=undefined) cb(resp);
let orderData = resp["order"]["jsonResponse"];
console.log(orderData);
if (orderData.id) {
// return orderData.id;
function createOrderCallback(){
// console.log(orderData);
return orderData.id;
}
function onApproveCallback(){
self.dp.appManager.apicall(`/v1/payments/paypal/orders/${orderData.id}/capture`,{
method: 'POST'
},function(resp){
console.log(resp);
if(cb!=undefined) cb(resp);
const orderData = resp; //await response.json();
// Three cases to handle:
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// (2) Other non-recoverable errors -> Show a failure message
// (3) Successful transaction -> Show confirmation or thank you message
const transaction =
orderData?.purchase_units?.[0]?.payments?.captures?.[0] ||
orderData?.purchase_units?.[0]?.payments?.authorizations?.[0];
const errorDetail = orderData?.details?.[0];
// this actions.restart() behavior only applies to the Buttons component
if (errorDetail?.issue === "INSTRUMENT_DECLINED" && !data.card && actions) {
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// recoverable state, per https://developer.paypal.com/docs/checkout/standard/customize/handle-funding-failures/
return actions.restart();
} else if (
errorDetail ||
!transaction ||
transaction.status === "DECLINED"
) {
// (2) Other non-recoverable errors -> Show a failure message
let errorMessage;
if (transaction) {
errorMessage = `Transaction ${transaction.status}: ${transaction.id}`;
} else if (errorDetail) {
errorMessage = `${errorDetail.description} (${orderData.debug_id})`;
} else {
errorMessage = JSON.stringify(orderData);
}
throw new Error(errorMessage);
} else {
// (3) Successful transaction -> Show confirmation or thank you message
// Or go to another URL: actions.redirect('thank_you.html');
resultMessage(
`Transaction ${transaction.status}: ${transaction.id}<br><br>See console for all available details`,
);
console.log( "Capture result", orderData, JSON.stringify(orderData, null, 2));
}
});
}
if(window==undefined){
console.log("window not defined");
return;
}
if(window.paypal==undefined){
console.log("Paypal not defined");
return;
}
window.paypal.Buttons({
createOrder: createOrderCallback,
onApprove: onApproveCallback,
}).render("#paypal-button-container");
const cardField = window.paypal.CardFields({
createOrder: createOrderCallback,
onApprove: onApproveCallback,
});
// Render each field after checking for eligibility
if (cardField.isEligible()) {
const nameField = cardField.NameField();
nameField.render("#card-name-field-container");
const numberField = cardField.NumberField();
numberField.render("#card-number-field-container");
const cvvField = cardField.CVVField();
cvvField.render("#card-cvv-field-container");
const expiryField = cardField.ExpiryField();
expiryField.render("#card-expiry-field-container");
// Add click listener to submit button and call the submit function on the CardField component
document
.getElementById("card-field-submit-button")
.addEventListener("click", () => {
cardField
.submit({
// From your billing address fields
billingAddress: {
addressLine1: document.getElementById("card-billing-address-line-1")
.value,
addressLine2: document.getElementById("card-billing-address-line-2")
.value,
adminArea1: document.getElementById(
"card-billing-address-admin-area-line-1",
).value,
adminArea2: document.getElementById(
"card-billing-address-admin-area-line-2",
).value,
countryCode: document.getElementById(
"card-billing-address-country-code",
).value,
postalCode: document.getElementById(
"card-billing-address-postal-code",
).value,
},
})
.catch((error) => {
resultMessage(
`Sorry, your transaction could not be processed...<br><br>${error}`,
);
});
});
} else {
// Hides card fields if the merchant isn't eligible
document.querySelector("#card-form").style = "display: none";
}
// Example function to show a result to the user. Your site's UI library can be used instead.
function resultMessage(message) {
const container = document.querySelector("#result-message");
container.innerHTML = message;
}
} else {
const errorDetail = orderData?.details?.[0];
const errorMessage = errorDetail
? `${errorDetail.issue} ${errorDetail.description} (${orderData.debug_id})`
: JSON.stringify(orderData);
throw new Error(errorMessage);
}
});
}
function __setupOptions(obj,myself){
// let self = {};
// self.container_id = obj.container_id;
// self.callbacks = {};
obj.contents = {};
obj.callbacks = {};
// options
if(obj.options==undefined){
obj.options = {};
}
obj.options.process = {};
if(obj.options.delay==undefined){
obj.options.delay = 500;
}
if(obj.options.container_id==undefined){
obj.options.container_id = "";
}
if(obj.options.appendNow==undefined){
obj.options.appendNow = true;
}
if(obj.options.showPaypalForm==undefined){
obj.options.showPaypalForm = true;
}
if(obj.options.showPaypalButton==undefined){
obj.options.showPaypalButton = true;
}
if(obj.options.paypal_error_message==undefined){
obj.options.paypal_error_message = "Sorry there was an error process your payment.";
}
if(obj.options.submit_button==undefined){
obj.options.submit_button = {id:"defualt_submit_button_id",label:"Submit"};
}
if(obj.options.onSubmit==undefined){
obj.options.onSubmit = {
id:"defualt_submit_button_id",
label:"Submit",
showButton:true
};
}
if(obj.options.termsAgreementText==undefined){
obj.options.termsAgreementText = `<div class="mt-3 d-flex justify-content-center">By clicking Donate you agree to the <a id="paypal_terms_and_conditions" href="#">Terms & Conditions</a></p></div>`;
}
if(obj.options.onSubmit.showButton==undefined || obj.options.onSubmit.showButton==true){
obj.options.onSubmit.htmlButton = `<button value="submit" id="${obj.options.onSubmit.id}" style="width: 100%; color: white" class="btn btn-success ${obj.options.submit_button.className}"><strong>${obj.options.onSubmit.label}</strong></button>`;
}else{
obj.options.onSubmit.htmlButton = "";
}
if(obj.options.overlayDelay==undefined){
obj.options.overlayDelay = 20000;
}
if(obj.options.billingAddressEnabled==undefined){
obj.options.billingAddressEnabled = false;
}
if(obj.options.billingAddressNameEnabled==undefined){
obj.options.billingAddressNameEnabled = false;
}
if(obj.options.no_reply_subject==undefined){
obj.options.no_reply_subject = "";
}
// self.options = obj.options;
// contents
if(obj.success_content==undefined){
obj.success_content = function(mydata){ return ""; };
}
obj.contents.success_content = obj.success_content;
// callbacks
if(obj.success_callback==undefined){
obj.success_callback = function(){};
}
obj.callbacks.success_callback = obj.success_callback;
if(obj.error_callback==undefined){
obj.error_callback = function(erre){};
}
obj.callbacks.error_callback = obj.error_callback;
if(obj.validation_callback==undefined){
console.log("validation_callback callbck not set");
obj.validation_callback = function(){return {pass:true}}
}
obj.callbacks.validation_callback = obj.validation_callback;
if(obj.validate_price_callback==undefined){
console.log("validate_price_callback callbck not set");
obj.validation_callback = function(){return {pass:true}}
}
obj.callbacks.validate_price_callback = obj.validate_price_callback;
if(obj.success_content==undefined){
console.log("success_content callbck not set");
obj.success_content = function(){return {pass:true}}
}
obj.callbacks.success_content = obj.success_content;
if(obj.button_onApprove_callback==undefined){
obj.button_onApprove_callback = function(){};
}
obj.callbacks.button_onApprove_callback = obj.button_onApprove_callback;
if(obj.button_onClick_callback==undefined){
obj.button_onClick_callback = function(){};
}
obj.callbacks.button_onClick_callback = obj.button_onClick_callback;
return obj;
}
return {
InitializeClientSDK: InitializeClientSDK,
DirectPayments: DirectPayments,
EmailHandler: EmailHandler,
payments: {
createNewDirectPayment
},
sendEmail,
useEmailGroup: function(id,emails,client_variables,mail_handlers,app){
let handlersClone = structuredClone(mail_handlers);
console.log(app.extra)
let managed_domain = app.extra.config.managed_domain;
let domain_settings = app.extra.config.configurations.domain_settings[0];
let email_handler = new EmailHandler(id,handlersClone,domain_settings,managed_domain);
if(email_handler.handler==null){
console.log(`Error No email group found for ${id}`);
}
email_handler.setupVariables(emails,client_variables);
return email_handler;
}
};
})));