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.1 to 1.2.2

2

dist/threedsecure-service.min.js

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

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}}}
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(()=>409===response.status||424===response.status||500==response.status||503==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=()=>{try{reject({status:xhr.status,data:tryParse(xhr.responseText)})}catch(error){reject({status:500,data:{message:error.toString()}})}},xhr.ontimeout=()=>{reject({status:503,data:{message:"Service timeout"}})};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.1",
"version": "1.2.2",
"description": "JS service implementation to control the 3DS flow over Paybyrd API",

@@ -5,0 +5,0 @@ "main": "dist/threedsecure-service.min.js",

@@ -53,2 +53,9 @@ # ThreeDSecure Service

* **purchaseCurrency:** The purchase currency folowwing the **ISO 4217 format**.
* **challengeOptions:** Indicator passed to ACS to indicate the configuration for challenge.
* **NoPreference:** Do not use any challenge options
* **NoChallenge:** Try to not require challenge
* **ThreeDSecurePreference:** Let 3DS choose the best option
* **Required:** Require challenge
> Sometimes, even when we require the challenge, the ACS will not ask for it, and the flow will run successfully until the end

@@ -62,3 +69,4 @@ ```js

purchaseAmount: 1,
purchaseCurrency: 'EUR'
purchaseCurrency: 'EUR',
challengeOptions: 'Required'
}

@@ -65,0 +73,0 @@

@@ -408,3 +408,9 @@ export default class ThreeDSecureService {

_isTransientStatusCode(response) {
return this._safeExecute(() => response.status == 500 || response.status === 409 || response.status === 424 || response.status === 504, true);
return this._safeExecute(() =>
response.status === 409
|| response.status === 424
|| response.status == 500
|| response.status == 503
|| response.status === 504,
true);
}

@@ -468,8 +474,28 @@

};
xhr.onerror = () => {
try {
reject({
status: xhr.status,
data: tryParse(xhr.responseText)
});
}
catch (error) {
reject({
status: 500,
data: {
message: error.toString()
}
});
}
};
xhr.ontimeout = () => {
reject({
status: xhr.status,
data: tryParse(xhr.responseText)
status: 503,
data: {
message: 'Service timeout'
}
});
}
};

@@ -476,0 +502,0 @@ const json = this._safeExecute(() => JSON.stringify(payload), '{}');

Sorry, the diff of this file is not supported yet

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