Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@paybyrd/threedsecure-service

Package Overview
Dependencies
Maintainers
5
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@paybyrd/threedsecure-service - npm Package Compare versions

Comparing version 1.2.0 to 1.2.1

samples/direct-usage-sample.html

2

dist/threedsecure-service.min.js

@@ -1,1 +0,1 @@

class ThreeDSecureService{constructor({threeDSecureUrl,container,maxAttempts,attemptDelay,culture,onProgressFn,onIFrameCreatedFn,onContainerCreatedFn}){this._onProgressFn=onProgressFn,this._maxAttempts=maxAttempts||50,this._attemptDelay=attemptDelay||2e3,this._threeDSecureUrl=threeDSecureUrl||"https://threedsecure.paybyrd.com",this._culture=culture||"en-US",this._container=container||document.body,this._onIFrameCreatedFn=onIFrameCreatedFn,this._onContainerCreatedFn=onContainerCreatedFn,this.IFRAME_DSMETHOD_NAME="threeDSMethodIframe",this.FORM_DSMETHOD_NAME="threeDSMethodForm",this.IFRAME_CHALLENGE_NAME="challengeIframe",this.FORM_CHALLENGE_NAME="challengeForm",this._fixContainer()}createAndExecute(initiatePayment,correlationId=crypto.randomUUID()){return this.create(initiatePayment,correlationId).then(createResponse=>this.preAuth(createResponse,correlationId)).then(preAuthResponse=>this.auth(preAuthResponse,correlationId)).then(authResponse=>this.postAuth(authResponse,correlationId)).then(postAuthResponse=>({...postAuthResponse,correlationId:correlationId})).catch(error=>Promise.reject({...error,correlationId:correlationId})).finally(this._destroy.bind(this))}create(initiatePayment,correlationId){return this._retry(this._isTransientStatusCode,()=>this._sendRequest({path:"/api/v1",method:"POST",payload:{...initiatePayment,browser:this._getBrowserData()},correlationId:correlationId}),"event:create")}preAuth(preAuthRequest,correlationId){return this._retry(this._isTransientStatusCode,()=>this._sendRequest({path:`/api/v1/${preAuthRequest.id}/preauth`,method:"POST",correlationId:correlationId}),"event:preAuth").then(preAuthResponse=>preAuthResponse.isDsMethodRequired?this._executeDsMethod(preAuthResponse).then(()=>preAuthResponse):preAuthResponse)}auth(authRequest,correlationId){return this._retry(this._isTransientStatusCode,()=>this._sendRequest({path:`/api/v1/${authRequest.id}/auth`,method:"POST",correlationId:correlationId}),"event:auth").then(authResponse=>authResponse.isChallengeRequired?("1.0.0"===authResponse.challengeVersion?this._executeChallengeV1(authResponse):this._executeChallengeV2(authResponse)).then(()=>authResponse):authResponse)}postAuth(postAuthRequest,correlationId){return this._retry(this._isTransientStatusCode,()=>this._sendRequest({path:`/api/v1/${postAuthRequest.id}/postAuth`,method:"POST",correlationId:correlationId}),"event:postAuth")}_executeDsMethod(preAuthResponse){return new Promise((resolve,reject)=>{try{this._onProgress({type:"event:dsMethod:start"});var iframeName=this.IFRAME_DSMETHOD_NAME,formName=this.FORM_DSMETHOD_NAME;this._createIFrame(iframeName,!1);const form=this._createForm(formName,preAuthResponse.dsMethodUrl,iframeName),threeDSMethodDataInput=this._createInput(form,"threeDSMethodData","hidden");var threeDSMethodData={threeDSServerTransID:preAuthResponse.processId,threeDSMethodNotificationURL:preAuthResponse.notificationUrl};threeDSMethodDataInput.value=this._convertToBase64UriJson(threeDSMethodData),form.submit(),this._onProgress({type:"event:dsMethod:success"}),resolve()}catch(error){return this._onProgress({type:"event:dsMethod:fail"}),reject({message:error.toString()})}})}_executeChallengeV1(authResponse){return new Promise((resolve,reject)=>{try{this._onProgress({type:"event:challenge:v1:start"});var iframeName=this.IFRAME_CHALLENGE_NAME,formName=this.FORM_CHALLENGE_NAME;this._createIFrame(iframeName);const form=this._createForm(formName,authResponse.challengeUrl,iframeName,"post"),paReqInput=this._createInput(form,"PaReq","hidden"),termUrlInput=this._createInput(form,"TermUrl","hidden");paReqInput.value=authResponse.preAuthRequest,termUrlInput.value=authResponse.notificationUrl,form.submit(),resolve(),this._onProgress({type:"event:challenge:v1:success"})}catch(error){return this._onProgress({type:"event:challenge:v1:fail",error:error}),reject({message:error.toString()})}})}_executeChallengeV2(authResponse){return new Promise((resolve,reject)=>{try{this._onProgress({type:"event:challenge:v2:start"});var iframeName=this.IFRAME_CHALLENGE_NAME,formName=this.FORM_CHALLENGE_NAME;this._createIFrame(iframeName);const form=this._createForm(formName,authResponse.challengeUrl,iframeName,"post"),threeDSRequestInput=(this._createInput(form,"threeDSSessionData","hidden"),this._createInput(form,"creq","hidden"));var cReq={threeDSServerTransID:authResponse.processId,acsTransID:authResponse.challengeId,messageVersion:authResponse.challengeVersion,messageType:"CReq",challengeWindowSize:"01"};threeDSRequestInput.value=this._convertToBase64UriJson(cReq),form.submit(),resolve(),this._onProgress({type:"event:challenge:v2:success"})}catch(error){return this._onProgress({type:"event:challenge:v2:fail",error:error}),reject({message:error.toString()})}})}_delay(timeout){return this._onProgress({type:"event:delay:start",data:{timeout:timeout}}),new Promise((resolve,_)=>{setTimeout(()=>{this._onProgress({type:"event:delay:end",data:{timeout:timeout}}),resolve()},timeout)})}_fixContainer(){this._onContainerCreatedFn?this._onContainerCreatedFn(this._container):this._container.setAttribute("style","position: relative; overflow: hidden;")}_createForm(name,action,target,method="POST"){const form=document.createElement("form");return form.id=name,form.name=name,form.action=action,form.target=target,form.method=method,this._container.appendChild(form),form}_createInput(form,name,type){const input=document.createElement("input");return input.id=name,input.name=name,input.type=type,form.appendChild(input),input}_createIFrame(name,visible=!0){const iframe=document.createElement("iframe");return iframe.id=name,iframe.name=name,this._onIFrameCreatedFn?(this._onIFrameCreatedFn(iframe),iframe.style.opacity=visible?1:0):iframe.setAttribute("style","border: none;position: absolute; top: 0; left: 0; bottom: 0; right: 0; width: 100%; height: 100%;opacity: "+(visible?"1":"0")),this._container.appendChild(iframe),iframe}_getBrowserData(){var colorDepth=[48,32,24,16,15,8,4,1].find(x=>x<=screen.colorDepth);return{javaEnabled:navigator.javaEnabled(),javascriptEnabled:!0,language:navigator.language,userAgent:navigator.userAgent,screenWidth:window.screen.width,screenHeight:window.screen.height,timezoneOffset:(new Date).getTimezoneOffset(),colorDepth:colorDepth,acceptHeader:"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"}}_retry(conditionFn,executeFn,eventType){return new Promise(async(resolve,reject)=>{let response=null,attempts=this._maxAttempts;do{this._onProgress({type:eventType+":start",data:{attempt:this._maxAttempts-attempts+1}});try{response=await executeFn()}catch(error){this._onProgress({type:eventType+":error",error:error.data?.error,data:{statusCode:error.status}}),response=error}if(200<=response.status&&response.status<300)return this._onProgress({type:eventType+":success",data:response.data.data}),void resolve(response.data.data)}while(attempts--,await this._delay(this._attemptDelay),0<attempts&&conditionFn(response));this._onProgress({type:eventType+":fail",error:response.data?.error}),reject(response.data?.error??{message:"Unhandled error"})})}_onProgress(event){try{this._onProgressFn?.call(null,event)}catch{}}_isTransientStatusCode(response){return 409===response.status||424===response.status||504===response.status}_convertToBase64UriJson(data){data=JSON.stringify(data);const base64Json=btoa(data);return base64Json.replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}_sendRequest({path,method,payload,correlationId}){const tryParse=json=>{if(""===json)return null;try{return JSON.parse(json)}catch{return null}};return new Promise((resolve,reject)=>{let xhr=new XMLHttpRequest;const url=new URL(path,this._threeDSecureUrl);xhr.open(method,url.toString());xhr.timeout=3e4,xhr.setRequestHeader("Accept","application/json"),xhr.setRequestHeader("Accept-Language",this._culture),xhr.setRequestHeader("Content-Type","application/json"),xhr.setRequestHeader("CorrelationId",correlationId),xhr.onload=()=>{(200<=xhr.status&&xhr.status<300?resolve:reject)({status:xhr.status,data:tryParse(xhr.responseText)})},xhr.onerror=()=>{reject({status:xhr.status,data:tryParse(xhr.responseText)})},xhr.send(JSON.stringify(payload))})}_destroy(){document.getElementById(this.IFRAME_DSMETHOD_NAME)?.remove(),document.getElementById(this.FORM_DSMETHOD_NAME)?.remove(),document.getElementById(this.IFRAME_CHALLENGE_NAME)?.remove(),document.getElementById(this.FORM_CHALLENGE_NAME)?.remove()}}export default ThreeDSecureService;
export default class ThreeDSecureService{constructor({threeDSecureUrl,container,maxAttempts,attemptDelay,culture,onProgressFn,onIFrameCreatedFn,onContainerCreatedFn}){this._onProgressFn=onProgressFn,this._maxAttempts=maxAttempts||50,this._attemptDelay=attemptDelay||2e3,this._threeDSecureUrl=threeDSecureUrl||"https://threedsecure.paybyrd.com",this._culture=culture||"en-US",this._container=container||document.body,this._onIFrameCreatedFn=onIFrameCreatedFn,this._onContainerCreatedFn=onContainerCreatedFn,this.IFRAME_DSMETHOD_NAME="threeDSMethodIframe",this.FORM_DSMETHOD_NAME="threeDSMethodForm",this.IFRAME_CHALLENGE_NAME="challengeIframe",this.FORM_CHALLENGE_NAME="challengeForm",this._fixContainer()}createAndExecute(initiatePayment,correlationId=crypto.randomUUID()){return this.create(initiatePayment,correlationId).then(createResponse=>this.preAuth(createResponse,correlationId)).then(preAuthResponse=>this.auth(preAuthResponse,correlationId)).then(authResponse=>this.postAuth(authResponse,correlationId)).then(postAuthResponse=>({...postAuthResponse,correlationId:correlationId})).catch(error=>Promise.reject({...error,correlationId:correlationId})).finally(this._destroy.bind(this))}create(initiatePayment,correlationId){return this._retry(this._isTransientStatusCode.bind(this),()=>this._sendRequest({path:"/api/v1",method:"POST",payload:{...initiatePayment,browser:this._getBrowserData()},correlationId:correlationId}),"event:create")}preAuth(preAuthRequest,correlationId){return this._retry(this._isTransientStatusCode.bind(this),()=>this._sendRequest({path:`/api/v1/${preAuthRequest.id}/preauth`,method:"POST",correlationId:correlationId}),"event:preAuth").then(preAuthResponse=>preAuthResponse.isDsMethodRequired?this._executeDsMethod(preAuthResponse).then(()=>preAuthResponse):preAuthResponse)}auth(authRequest,correlationId){return this._retry(this._isTransientStatusCode.bind(this),()=>this._sendRequest({path:`/api/v1/${authRequest.id}/auth`,method:"POST",correlationId:correlationId}),"event:auth").then(authResponse=>authResponse.isChallengeRequired?("1.0.0"===authResponse.challengeVersion?this._executeChallengeV1(authResponse):this._executeChallengeV2(authResponse)).then(()=>authResponse):authResponse)}postAuth(postAuthRequest,correlationId){return this._retry(this._isTransientStatusCode.bind(this),()=>this._sendRequest({path:`/api/v1/${postAuthRequest.id}/postAuth`,method:"POST",correlationId:correlationId}),"event:postAuth")}_executeDsMethod(preAuthResponse){return new Promise((resolve,reject)=>{try{this._onProgress({type:"event:dsMethod:start"});var iframeName=this.IFRAME_DSMETHOD_NAME,formName=this.FORM_DSMETHOD_NAME;this._createIFrame(iframeName,!1);const form=this._createForm(formName,preAuthResponse.dsMethodUrl,iframeName),threeDSMethodDataInput=this._createInput(form,"threeDSMethodData","hidden");var threeDSMethodData={threeDSServerTransID:preAuthResponse.processId,threeDSMethodNotificationURL:preAuthResponse.notificationUrl};threeDSMethodDataInput.value=this._convertToBase64UriJson(threeDSMethodData),form.submit(),this._onProgress({type:"event:dsMethod:success"}),resolve()}catch(error){return this._onProgress({type:"event:dsMethod:fail"}),reject({message:error.toString()})}})}_executeChallengeV1(authResponse){return new Promise((resolve,reject)=>{try{this._onProgress({type:"event:challenge:v1:start"});var iframeName=this.IFRAME_CHALLENGE_NAME,formName=this.FORM_CHALLENGE_NAME;this._createIFrame(iframeName);const form=this._createForm(formName,authResponse.challengeUrl,iframeName,"post"),paReqInput=this._createInput(form,"PaReq","hidden"),termUrlInput=this._createInput(form,"TermUrl","hidden");paReqInput.value=authResponse.preAuthRequest,termUrlInput.value=authResponse.notificationUrl,form.submit(),resolve(),this._onProgress({type:"event:challenge:v1:success"})}catch(error){return this._onProgress({type:"event:challenge:v1:fail",error:error}),reject({message:error.toString()})}})}_executeChallengeV2(authResponse){return new Promise((resolve,reject)=>{try{this._onProgress({type:"event:challenge:v2:start"});var iframeName=this.IFRAME_CHALLENGE_NAME,formName=this.FORM_CHALLENGE_NAME;this._createIFrame(iframeName);const form=this._createForm(formName,authResponse.challengeUrl,iframeName,"post"),threeDSRequestInput=(this._createInput(form,"threeDSSessionData","hidden"),this._createInput(form,"creq","hidden"));var cReq={threeDSServerTransID:authResponse.processId,acsTransID:authResponse.challengeId,messageVersion:authResponse.challengeVersion,messageType:"CReq",challengeWindowSize:"01"};threeDSRequestInput.value=this._convertToBase64UriJson(cReq),form.submit(),resolve(),this._onProgress({type:"event:challenge:v2:success"})}catch(error){return this._onProgress({type:"event:challenge:v2:fail",error:error}),reject({message:error.toString()})}})}_delay(timeout){return this._onProgress({type:"event:delay:start",data:{timeout:timeout}}),new Promise((resolve,_)=>{setTimeout(()=>{this._onProgress({type:"event:delay:end",data:{timeout:timeout}}),resolve()},timeout)})}_fixContainer(){this._onContainerCreatedFn?this._onContainerCreatedFn(this._container):this._container.setAttribute("style","position: relative; overflow: hidden;")}_createForm(name,action,target,method="POST"){const form=document.createElement("form");return form.id=name,form.name=name,form.action=action,form.target=target,form.method=method,this._container.appendChild(form),form}_createInput(form,name,type){const input=document.createElement("input");return input.id=name,input.name=name,input.type=type,form.appendChild(input),input}_createIFrame(name,visible=!0){const iframe=document.createElement("iframe");return iframe.id=name,iframe.name=name,this._onIFrameCreatedFn?(this._onIFrameCreatedFn(iframe),iframe.style.opacity=visible?1:0):iframe.setAttribute("style","border: none;position: absolute; top: 0; left: 0; bottom: 0; right: 0; width: 100%; height: 100%;opacity: "+(visible?"1":"0")),this._container.appendChild(iframe),iframe}_getBrowserData(){var colorDepth=[48,32,24,16,15,8,4,1].find(x=>x<=screen.colorDepth);return{javaEnabled:navigator.javaEnabled(),javascriptEnabled:!0,language:navigator.language,userAgent:navigator.userAgent,screenWidth:window.screen.width,screenHeight:window.screen.height,timezoneOffset:(new Date).getTimezoneOffset(),colorDepth:colorDepth,acceptHeader:"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"}}_retry(conditionFn,executeFn,eventType){return new Promise(async(resolve,reject)=>{let response=null,attempts=this._maxAttempts;do{this._onProgress({type:eventType+":start",data:{attempt:this._maxAttempts-attempts+1}});try{response=await executeFn()}catch(error){this._onProgress({type:eventType+":error",error:error.data?.error,data:{statusCode:error.status}}),response=error}if(200<=response.status&&response.status<300)return this._onProgress({type:eventType+":success",data:response.data.data}),void resolve(response.data.data)}while(attempts--,await this._delay(this._attemptDelay),0<attempts&&conditionFn(response));this._onProgress({type:eventType+":fail",error:response.data?.error}),reject(response.data?.error??{message:"Unhandled error"})})}_onProgress(event){this._safeExecute(()=>this._onProgressFn?.call(null,event))}_isTransientStatusCode(response){return this._safeExecute(()=>500==response.status||409===response.status||424===response.status||504===response.status,!0)}_convertToBase64UriJson(data){data=JSON.stringify(data);const base64Json=btoa(data);return base64Json.replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}_sendRequest({path,method,payload,correlationId}){const tryParse=json=>""===json?null:this._safeExecute(()=>JSON.parse(json),null);return new Promise((resolve,reject)=>{let xhr=new XMLHttpRequest;const url=new URL(path,this._threeDSecureUrl);xhr.open(method,url.toString());xhr.timeout=3e4,xhr.setRequestHeader("Accept","application/json"),xhr.setRequestHeader("Accept-Language",this._culture),xhr.setRequestHeader("Content-Type","application/json"),xhr.setRequestHeader("CorrelationId",correlationId),xhr.onload=()=>{try{if(200<=xhr.status&&xhr.status<300)return void resolve({status:xhr.status,data:tryParse(xhr.responseText)});reject({status:xhr.status,data:tryParse(xhr.responseText)})}catch(error){console.log(error),reject({status:500,data:{message:error.toString()}})}},xhr.onerror=()=>{reject({status:xhr.status,data:tryParse(xhr.responseText)})};var json=this._safeExecute(()=>JSON.stringify(payload),"{}");xhr.send(json)})}_destroy(){this._safeExecute(()=>document.getElementById(this.IFRAME_DSMETHOD_NAME)?.remove()),this._safeExecute(()=>document.getElementById(this.FORM_DSMETHOD_NAME)?.remove()),this._safeExecute(()=>document.getElementById(this.IFRAME_CHALLENGE_NAME)?.remove()),this._safeExecute(()=>document.getElementById(this.FORM_CHALLENGE_NAME)?.remove())}_safeExecute(action,defaultResult){try{return action()}catch(error){return console.log(error),defaultResult}}}
{
"name": "@paybyrd/threedsecure-service",
"version": "1.2.0",
"version": "1.2.1",
"description": "JS service implementation to control the 3DS flow over Paybyrd API",

@@ -11,3 +11,4 @@ "main": "dist/threedsecure-service.min.js",

"scripts": {
"prepublish": "uglifyjs src/threedsecure-service.js -c -o dist/threedsecure-service.min.js"
"prepublish": "uglifyjs src/threedsecure-service.js -c -o dist/threedsecure-service.min.js",
"samples": "live-server --open=./samples"
},

@@ -29,4 +30,5 @@ "keywords": [

"devDependencies": {
"uglify-js": "^3.16.2"
"uglify-js": "^3.16.2",
"live-server": "1.2.2"
}
}

@@ -1,2 +0,2 @@

class ThreeDSecureService {
export default class ThreeDSecureService {
constructor({

@@ -51,3 +51,3 @@ threeDSecureUrl,

return this._retry(
this._isTransientStatusCode,
this._isTransientStatusCode.bind(this),
() => this._sendRequest({

@@ -67,3 +67,3 @@ path: '/api/v1',

return this._retry(
this._isTransientStatusCode,
this._isTransientStatusCode.bind(this),
() => this._sendRequest({

@@ -87,3 +87,3 @@ path: `/api/v1/${preAuthRequest.id}/preauth`,

return this._retry(
this._isTransientStatusCode,
this._isTransientStatusCode.bind(this),
() => this._sendRequest({

@@ -110,3 +110,3 @@ path: `/api/v1/${authRequest.id}/auth`,

return this._retry(
this._isTransientStatusCode,
this._isTransientStatusCode.bind(this),
() => this._sendRequest({

@@ -408,13 +408,7 @@ path: `/api/v1/${postAuthRequest.id}/postAuth`,

_onProgress(event) {
try {
this._onProgressFn?.call(null, event);
} catch
{
// do nothing
}
this._safeExecute(() => this._onProgressFn?.call(null, event));
}
_isTransientStatusCode(response) {
return response.status === 409 || response.status === 424 || response.status === 504;
return this._safeExecute(() => response.status == 500 || response.status === 409 || response.status === 424 || response.status === 504, true);
}

@@ -437,7 +431,3 @@

}
try {
return JSON.parse(json);
} catch {
return null;
}
return this._safeExecute(() => JSON.parse(json), null);
}

@@ -449,3 +439,2 @@

xhr.open(method, url.toString());

@@ -462,13 +451,24 @@

xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
resolve({
try {
if (xhr.status >= 200 && xhr.status < 300) {
resolve({
status: xhr.status,
data: tryParse(xhr.responseText)
});
return;
}
reject({
status: xhr.status,
data: tryParse(xhr.responseText)
});
return;
}
reject({
status: xhr.status,
data: tryParse(xhr.responseText)
});
catch (error) {
console.log(error);
reject({
status: 500,
data: {
message: error.toString()
}
});
}
};

@@ -482,3 +482,5 @@ xhr.onerror = () => {

xhr.send(JSON.stringify(payload));
const json = this._safeExecute(() => JSON.stringify(payload), '{}');
xhr.send(json);
});

@@ -488,9 +490,16 @@ }

_destroy() {
document.getElementById(this.IFRAME_DSMETHOD_NAME)?.remove();
document.getElementById(this.FORM_DSMETHOD_NAME)?.remove();
document.getElementById(this.IFRAME_CHALLENGE_NAME)?.remove();
document.getElementById(this.FORM_CHALLENGE_NAME)?.remove();
this._safeExecute(() => document.getElementById(this.IFRAME_DSMETHOD_NAME)?.remove());
this._safeExecute(() => document.getElementById(this.FORM_DSMETHOD_NAME)?.remove());
this._safeExecute(() => document.getElementById(this.IFRAME_CHALLENGE_NAME)?.remove());
this._safeExecute(() => document.getElementById(this.FORM_CHALLENGE_NAME)?.remove());
}
}
export default ThreeDSecureService;
_safeExecute(action, defaultResult) {
try {
return action();
} catch (error) {
console.log(error);
return defaultResult;
}
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc