@stitch-money/client 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.d.ts CHANGED
@@ -12,6 +12,7 @@ interface StitchTransaction {
12
12
  nonce: string;
13
13
  status: StitchTransactionState;
14
14
  statusReason?: string | null;
15
+ interactionUrl?: string | null;
15
16
  }
16
17
  interface StitchWalletClientInitialisationProperties {
17
18
  onCancelPayment?: () => void;
@@ -57,9 +58,9 @@ declare class StitchWalletClientSdk {
57
58
  /**
58
59
  * Initializes a StitchWalletClientSdk instance
59
60
  *
60
- * @param {StitchWalletClientInitialisationProperties} intialisationProperties
61
+ * @param {StitchWalletClientInitialisationProperties} initialisationProperties
61
62
  */
62
- constructor(intialisationProperties: StitchWalletClientInitialisationProperties);
63
+ constructor(initialisationProperties: StitchWalletClientInitialisationProperties);
63
64
  /**
64
65
  * Returns a list of wallet payment methods supported on the device and/or browser
65
66
  *
package/build/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  "use client"
2
- var A=Object.defineProperty;var C=(a,e,t)=>e in a?A(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var m=(a,e,t)=>(C(a,typeof e!="symbol"?e+"":e,t),t);var l=(a,e,t)=>new Promise((s,c)=>{var y=n=>{try{i(t.next(n))}catch(r){c(r)}},u=n=>{try{i(t.throw(n))}catch(r){c(r)}},i=n=>n.done?s(n.value):Promise.resolve(n.value).then(y,u);i((t=t.apply(a,e)).next())});var f=(s=>(s.ApplePay="APPLE_PAY",s.SamsungPay="SAMSUNG_PAY",s.GooglePay="GOOGLE_PAY",s))(f||{});function S(){return window.ApplePaySession?ApplePaySession.canMakePayments():!1}function b(){if(!window.ApplePaySession)return-1;let e=t=>t===0?-1:ApplePaySession.supportsVersion(t)?t:e(t-1);return e(14)}function g(){return!!window}var o=class extends Error{constructor(e){super(e),this.name="SessionError"}};var P=a=>a instanceof Error?a.toString():JSON.stringify(a);var k="9ba67dd8d5b247cfb3f76e",h=class{constructor(e){m(this,"onCancelPayment");m(this,"applePayIsSupported");m(this,"samsungPayIsSupported");m(this,"googlePayIsSupported");let{onCancelPayment:t}=e;this.applePayIsSupported=S(),this.samsungPayIsSupported=g(),this.googlePayIsSupported=!0,this.onCancelPayment=t!=null?t:()=>{}}supportedPaymentMethods(){return l(this,null,function*(){let e=[];return this.applePayIsSupported=S(),this.applePayIsSupported&&e.push("APPLE_PAY"),this.samsungPayIsSupported=g(),this.samsungPayIsSupported&&e.push("SAMSUNG_PAY"),this.googlePayIsSupported&&e.push("GOOGLE_PAY"),e})}onClickApplePaySessionHandler(e,t,s,c,y){let u=b();return()=>{let i={countryCode:"ZA",currencyCode:e,supportedNetworks:["visa","masterCard"],merchantCapabilities:["supports3DS"],total:{label:s,amount:t.toString()}},n=new ApplePaySession(u,i);n.onvalidatemerchant=r=>l(this,null,function*(){try{let p=yield c(r.validationURL);n.completeMerchantValidation(p)}catch(p){throw new o(`Failed to complete merchant validation: ${P(p)}`)}}),n.onpaymentauthorized=r=>l(this,null,function*(){try{let p=r.payment.token,d=yield y(p);switch(d.status){case"TransactionPending":case"TransactionSuccess":{n.completePayment(ApplePaySession.STATUS_SUCCESS);break}case"TransactionFailure":{n.completePayment(ApplePaySession.STATUS_FAILURE);break}default:throw new o(`Invalid transaction status: ${d.status}`)}}catch(p){throw n.completePayment(ApplePaySession.STATUS_FAILURE),new o(`Failed to create payment: ${P(p)}`)}}),n.oncancel=()=>{this.onCancelPayment()},n.begin()}}onClickSamsungPaySessionHandler(e,t,s,c,y){return()=>l(this,null,function*(){let u=yield y(t,e),{id:i,href:n,encInfo:r}=u;if(window!=null&&window.SamsungPay)window.SamsungPay.connect(i,n,k,s,c,"uk",r.mod,r.exp,r.keyId);else throw new o("Samsung Pay client unavailable")})}onClickGooglePaySessionHandler(e){return t=>l(this,null,function*(){try{let s=yield e(t.paymentMethodData.tokenizationData.token);switch(s.status){case"TransactionPending":case"TransactionFailure":case"TransactionSuccess":break;default:throw new o(`Invalid transaction status: ${s.status}`)}}catch(s){throw new o(`Failed to create payment: ${P(s)}`)}})}};export{h as StitchWalletClientSdk,f as WalletType};
2
+ var C=Object.defineProperty;var k=(a,e,t)=>e in a?C(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var m=(a,e,t)=>(k(a,typeof e!="symbol"?e+"":e,t),t);var c=(a,e,t)=>new Promise((r,l)=>{var u=n=>{try{i(t.next(n))}catch(s){l(s)}},y=n=>{try{i(t.throw(n))}catch(s){l(s)}},i=n=>n.done?r(n.value):Promise.resolve(n.value).then(u,y);i((t=t.apply(a,e)).next())});var b=(r=>(r.ApplePay="APPLE_PAY",r.SamsungPay="SAMSUNG_PAY",r.GooglePay="GOOGLE_PAY",r))(b||{});function g(){return window.ApplePaySession?ApplePaySession.canMakePayments():!1}function h(){if(!window.ApplePaySession)return-1;let e=t=>t===0?-1:ApplePaySession.supportsVersion(t)?t:e(t-1);return e(14)}function S(){return/android/i.test(navigator.userAgent)}function d(){return console.log("determineSamsungPaySupport: PaymentRequest present:",window.PaymentRequest),console.log("determineSamsungPaySupport: SamsungPay present:",window.SamsungPay),console.log("determineSamsungPaySupport: UserAgent value:",navigator.userAgent),S()}var o=class extends Error{constructor(e){super(e),this.name="SessionError"}};var P=a=>a instanceof Error?a.toString():JSON.stringify(a);var w="9ba67dd8d5b247cfb3f76e",A=class{constructor(e){m(this,"onCancelPayment");m(this,"applePayIsSupported");m(this,"samsungPayIsSupported");m(this,"googlePayIsSupported");let{onCancelPayment:t}=e;this.applePayIsSupported=g(),this.samsungPayIsSupported=d(),this.googlePayIsSupported=S(),this.onCancelPayment=t!=null?t:()=>{}}supportedPaymentMethods(){return c(this,null,function*(){let e=[];return this.applePayIsSupported=g(),this.applePayIsSupported&&e.push("APPLE_PAY"),this.samsungPayIsSupported=d(),this.samsungPayIsSupported&&e.push("SAMSUNG_PAY"),this.googlePayIsSupported&&e.push("GOOGLE_PAY"),e})}onClickApplePaySessionHandler(e,t,r,l,u){let y=h();return()=>{let i={countryCode:"ZA",currencyCode:e,supportedNetworks:["visa","masterCard"],merchantCapabilities:["supports3DS"],total:{label:r,amount:t.toString()}},n=new ApplePaySession(y,i);n.onvalidatemerchant=s=>c(this,null,function*(){try{let p=yield l(s.validationURL);n.completeMerchantValidation(p)}catch(p){throw new o(`Failed to complete merchant validation: ${P(p)}`)}}),n.onpaymentauthorized=s=>c(this,null,function*(){try{let p=s.payment.token,f=yield u(p);switch(f.status){case"TransactionPending":case"TransactionSuccess":{n.completePayment(ApplePaySession.STATUS_SUCCESS);break}case"TransactionFailure":{n.completePayment(ApplePaySession.STATUS_FAILURE);break}default:throw new o(`Invalid transaction status: ${f.status}`)}}catch(p){throw n.completePayment(ApplePaySession.STATUS_FAILURE),new o(`Failed to create payment: ${P(p)}`)}}),n.oncancel=()=>{this.onCancelPayment()},n.begin()}}onClickSamsungPaySessionHandler(e,t,r,l,u){return()=>c(this,null,function*(){let y=yield u(t,e),{id:i,href:n,encInfo:s}=y;if(window!=null&&window.SamsungPay)window.SamsungPay.connect(i,n,w,r,l,"uk",s.mod,s.exp,s.keyId);else throw new o("Samsung Pay client unavailable")})}onClickGooglePaySessionHandler(e){return t=>c(this,null,function*(){try{let r=yield e(t.paymentMethodData.tokenizationData.token);switch(r.status){case"TransactionPending":case"TransactionFailure":case"TransactionSuccess":break;default:throw new o(`Invalid transaction status: ${r.status}`)}}catch(r){throw new o(`Failed to create payment: ${P(r)}`)}})}};export{A as StitchWalletClientSdk,b as WalletType};
3
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/utils/browser-support.ts","../src/utils/errors.ts","../src/utils/helpers.ts","../src/wallets/client.ts"],"sourcesContent":["export enum WalletType {\n ApplePay = 'APPLE_PAY',\n SamsungPay = 'SAMSUNG_PAY',\n GooglePay = 'GOOGLE_PAY',\n}\n\nexport type StitchTransactionState =\n | 'TransactionPending'\n | 'TransactionSuccess'\n | 'TransactionFailure';\n\nexport interface StitchTransaction {\n id: string;\n externalReference: string;\n quantity: number;\n currency: string;\n nonce: string;\n status: StitchTransactionState;\n statusReason?: string | null;\n}\nexport interface StitchWalletClientInitialisationProperties {\n onCancelPayment?: () => void;\n}\n\nexport type WalletPaySession = ApplePaySession | SamsungPaySession;\n\nexport interface ApplePaySession {\n epochTimestamp: number;\n expiresAt: number;\n merchantSessionIdentifier: string;\n nonce: string;\n merchantIdentifier: string;\n domainName: string;\n displayName: string;\n signature: string;\n operationalAnalyticsIdentifier: string;\n retries: number;\n pspId: string;\n}\nexport interface SamsungPaySession {\n id: string;\n href: string;\n encInfo: {\n mod: string;\n exp: string;\n keyId: string;\n };\n}\n\nexport type ApplePayVerifyCallback = (url: string) => Promise<WalletPaySession>;\nexport type SamsungPayVerifyCallback = (\n amount: number,\n currency: string,\n) => Promise<WalletPaySession>;\n\nexport type CreatePaymentCallback = (\n paymentToken:\n | ApplePayJS.ApplePayPaymentToken\n | google.payments.api.PaymentMethodTokenizationData['token'],\n) => Promise<CreatePaymentCallbackResponse>;\n\nexport interface CreatePaymentCallbackResponse {\n status: StitchTransaction['status'];\n}\n","interface SamsungPay {\n connect: (\n transactionId: string,\n href: string,\n serviceId: string,\n callbackUrl: string,\n cancelUrl: string,\n countryCode: string,\n // eslint-disable-next-line unicorn/prevent-abbreviations\n publicKeyMod: string,\n publicKeyExp: string,\n keyId: string,\n ) => void;\n}\n\ndeclare global {\n interface Window {\n ApplePaySession: ApplePaySession;\n SamsungPay: SamsungPay;\n }\n}\n\n/**\n * Determines whether Apple Pay is supported by the device.\n *\n * @returns {boolean} Whether Apple Pay is supported.\n */\nexport function determineApplePaySupport(): boolean {\n if (!window.ApplePaySession) {\n return false;\n }\n return ApplePaySession.canMakePayments();\n}\n\n/**\n * Determines the maximum supported Apple Pay version by the browser.\n *\n * @returns {number} The maximum supported version, or -1 if unsupported.\n */\nexport function getApplePayVersion(): number {\n const noSupportedVersion = -1;\n if (!window.ApplePaySession) {\n return noSupportedVersion;\n }\n\n const findMaxSupportedVersion = (version: number): number => {\n if (version === 0) return noSupportedVersion;\n if (ApplePaySession.supportsVersion(version)) {\n return version;\n }\n return findMaxSupportedVersion(version - 1);\n };\n\n return findMaxSupportedVersion(14);\n}\n\n/**\n * Determines whether Samsung Pay is supported by the browser.\n *\n * @returns {boolean} Whether Samsung Pay is supported.\n */\nexport function determineSamsungPaySupport(): boolean {\n return !!window;\n}\n","export class ApiError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\nexport class UserInputError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'UserInputError';\n }\n}\n\nexport class SessionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'SessionError';\n }\n}\n","/**\n * Converts any error object into a string representation.\n *\n * @param {unknown} error - The error object to convert.\n * @returns {string} String representation of the error.\n */\nexport const getErrorAsString = (error: unknown): string => {\n return error instanceof Error ? error.toString() : JSON.stringify(error);\n};\n","import {\n WalletType,\n type ApplePayVerifyCallback,\n type CreatePaymentCallback,\n type SamsungPaySession,\n type SamsungPayVerifyCallback,\n type StitchWalletClientInitialisationProperties,\n} from 'src/types';\nimport {\n determineApplePaySupport,\n determineSamsungPaySupport,\n getApplePayVersion,\n} from 'src/utils/browser-support';\nimport { SessionError } from 'src/utils/errors';\nimport { getErrorAsString } from 'src/utils/helpers';\n\nconst SAMSUNG_PAY_SERVICE_ID = '9ba67dd8d5b247cfb3f76e';\n\n/**\n * Client-side SDK for handling Stitch wallet payments\n */\nexport class StitchWalletClientSdk {\n private readonly onCancelPayment: () => void;\n\n private applePayIsSupported: boolean;\n private samsungPayIsSupported: boolean;\n // eslint-disable-next-line @typescript-eslint/prefer-readonly\n private googlePayIsSupported: boolean;\n\n /**\n * Initializes a StitchWalletClientSdk instance\n *\n * @param {StitchWalletClientInitialisationProperties} intialisationProperties\n */\n constructor(intialisationProperties: StitchWalletClientInitialisationProperties) {\n const { onCancelPayment } = intialisationProperties;\n this.applePayIsSupported = determineApplePaySupport();\n this.samsungPayIsSupported = determineSamsungPaySupport();\n this.googlePayIsSupported = true;\n this.onCancelPayment = onCancelPayment ?? (() => {});\n }\n\n /**\n * Returns a list of wallet payment methods supported on the device and/or browser\n *\n * @returns {Promise<WalletType[]>} Array of supported payment methods\n */\n public async supportedPaymentMethods(): Promise<WalletType[]> {\n const supportedWallets: WalletType[] = [];\n\n this.applePayIsSupported = determineApplePaySupport();\n if (this.applePayIsSupported) {\n supportedWallets.push(WalletType.ApplePay);\n }\n\n this.samsungPayIsSupported = determineSamsungPaySupport();\n if (this.samsungPayIsSupported) {\n supportedWallets.push(WalletType.SamsungPay);\n }\n\n if (this.googlePayIsSupported) {\n supportedWallets.push(WalletType.GooglePay);\n }\n\n return supportedWallets;\n }\n\n /**\n * Returns a onClick handler function for an Apple Pay session encapsulating merchant validation and payment creation\n *\n * @param {string} currency - Payment currency in ISO 4127 format e.g. ZAR.\n * @param {number} amount - Payment amount.\n * @param {string} label - Payment sheet label\n * @param {ApplePayVerifyCallback} verifyCallback - Callback for merchant validation.\n * @param {CreatePaymentCallback} createPaymentCallback - Callback for payment creation.\n * @returns {() => void} Function to handle Apple Pay button interaction\n */\n public onClickApplePaySessionHandler(\n currency: string,\n amount: number,\n label: string,\n verifyCallback: ApplePayVerifyCallback,\n createPaymentCallback: CreatePaymentCallback,\n ): () => void {\n const version = getApplePayVersion();\n\n return () => {\n const request: ApplePayJS.ApplePayPaymentRequest = {\n countryCode: 'ZA',\n currencyCode: currency,\n supportedNetworks: ['visa', 'masterCard'],\n merchantCapabilities: ['supports3DS'],\n total: {\n label,\n amount: amount.toString(),\n },\n };\n const session = new ApplePaySession(version, request);\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n session.onvalidatemerchant = async (event) => {\n try {\n const verifyCallbackResponse = await verifyCallback(event.validationURL);\n session.completeMerchantValidation(verifyCallbackResponse);\n } catch (error) {\n throw new SessionError(\n `Failed to complete merchant validation: ${getErrorAsString(error)}`,\n );\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n session.onpaymentauthorized = async (event) => {\n try {\n const paymentToken = event.payment.token;\n const createPaymentCallbackResponse = await createPaymentCallback(paymentToken);\n\n switch (createPaymentCallbackResponse.status) {\n case 'TransactionPending':\n case 'TransactionSuccess': {\n session.completePayment(ApplePaySession.STATUS_SUCCESS);\n break;\n }\n case 'TransactionFailure': {\n session.completePayment(ApplePaySession.STATUS_FAILURE);\n break;\n }\n default: {\n throw new SessionError(\n `Invalid transaction status: ${createPaymentCallbackResponse.status}`,\n );\n }\n }\n } catch (error) {\n session.completePayment(ApplePaySession.STATUS_FAILURE);\n throw new SessionError(`Failed to create payment: ${getErrorAsString(error)}`);\n }\n };\n // eslint-disable-next-line unicorn/prefer-add-event-listener\n session.oncancel = () => {\n this.onCancelPayment();\n };\n\n session.begin();\n };\n }\n\n /**\n * Returns a onClick handler function for a Samsung Pay session encapsulating payment verification and creation\n *\n * @param {string} currency - Payment currency in ISO 4127 format e.g. ZAR.\n * @param {number} amount - Payment amount.\n * @param {string} callbackUrl - Payment callback URL.\n * @param {number} cancelUrl - Payment cancellation URL.\n * @param {SamsungPayVerifyCallback} verifyCallback - Callback for payment verification.\n * @returns {() => void} Function to handle Apple Pay button interaction\n */\n public onClickSamsungPaySessionHandler(\n currency: string,\n amount: number,\n callbackUrl: string,\n cancelUrl: string,\n verifyCallback: SamsungPayVerifyCallback,\n ): () => Promise<void> {\n return async () => {\n const verifyCallbackResponse = await verifyCallback(amount, currency);\n const { id, href, encInfo } = verifyCallbackResponse as SamsungPaySession;\n\n if (window?.SamsungPay) {\n window.SamsungPay.connect(\n id,\n href,\n SAMSUNG_PAY_SERVICE_ID,\n callbackUrl,\n cancelUrl,\n 'uk',\n encInfo.mod,\n encInfo.exp,\n encInfo.keyId,\n );\n } else {\n throw new SessionError('Samsung Pay client unavailable');\n }\n };\n }\n\n public onClickGooglePaySessionHandler(\n createPaymentCallback: CreatePaymentCallback,\n ): (paymentData: google.payments.api.PaymentData) => void {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n return async (paymentData) => {\n try {\n const createPaymentCallbackResponse = await createPaymentCallback(\n paymentData.paymentMethodData.tokenizationData.token,\n );\n\n switch (createPaymentCallbackResponse.status) {\n case 'TransactionPending':\n case 'TransactionFailure':\n case 'TransactionSuccess': {\n break;\n }\n default: {\n throw new SessionError(\n `Invalid transaction status: ${createPaymentCallbackResponse.status}`,\n );\n }\n }\n } catch (error) {\n throw new SessionError(`Failed to create payment: ${getErrorAsString(error)}`);\n }\n };\n }\n}\n"],"mappings":";qXAAO,IAAKA,OACRA,EAAA,SAAW,YACXA,EAAA,WAAa,cACbA,EAAA,UAAY,aAHJA,OAAA,IC2BL,SAASC,GAAoC,CAChD,OAAK,OAAO,gBAGL,gBAAgB,gBAAgB,EAF5B,EAGf,CAOO,SAASC,GAA6B,CAEzC,GAAI,CAAC,OAAO,gBACR,MAAO,GAGX,IAAMC,EAA2BC,GACzBA,IAAY,EAAU,GACtB,gBAAgB,gBAAgBA,CAAO,EAChCA,EAEJD,EAAwBC,EAAU,CAAC,EAG9C,OAAOD,EAAwB,EAAE,CACrC,CAOO,SAASE,GAAsC,CAClD,MAAO,CAAC,CAAC,MACb,CCjDO,IAAMC,EAAN,cAA2B,KAAM,CACpC,YAAYC,EAAiB,CACzB,MAAMA,CAAO,EACb,KAAK,KAAO,cAChB,CACJ,ECbO,IAAMC,EAAoBC,GACtBA,aAAiB,MAAQA,EAAM,SAAS,EAAI,KAAK,UAAUA,CAAK,ECS3E,IAAMC,EAAyB,yBAKlBC,EAAN,KAA4B,CAa/B,YAAYC,EAAqE,CAZjFC,EAAA,KAAiB,mBAEjBA,EAAA,KAAQ,uBACRA,EAAA,KAAQ,yBAERA,EAAA,KAAQ,wBAQJ,GAAM,CAAE,gBAAAC,CAAgB,EAAIF,EAC5B,KAAK,oBAAsBG,EAAyB,EACpD,KAAK,sBAAwBC,EAA2B,EACxD,KAAK,qBAAuB,GAC5B,KAAK,gBAAkBF,GAAA,KAAAA,EAAoB,IAAM,CAAC,CACtD,CAOa,yBAAiD,QAAAG,EAAA,sBAC1D,IAAMC,EAAiC,CAAC,EAExC,YAAK,oBAAsBH,EAAyB,EAChD,KAAK,qBACLG,EAAiB,gBAAwB,EAG7C,KAAK,sBAAwBF,EAA2B,EACpD,KAAK,uBACLE,EAAiB,kBAA0B,EAG3C,KAAK,sBACLA,EAAiB,iBAAyB,EAGvCA,CACX,GAYO,8BACHC,EACAC,EACAC,EACAC,EACAC,EACU,CACV,IAAMC,EAAUC,EAAmB,EAEnC,MAAO,IAAM,CACT,IAAMC,EAA6C,CAC/C,YAAa,KACb,aAAcP,EACd,kBAAmB,CAAC,OAAQ,YAAY,EACxC,qBAAsB,CAAC,aAAa,EACpC,MAAO,CACH,MAAAE,EACA,OAAQD,EAAO,SAAS,CAC5B,CACJ,EACMO,EAAU,IAAI,gBAAgBH,EAASE,CAAO,EAEpDC,EAAQ,mBAA4BC,GAAUX,EAAA,sBAC1C,GAAI,CACA,IAAMY,EAAyB,MAAMP,EAAeM,EAAM,aAAa,EACvED,EAAQ,2BAA2BE,CAAsB,CAC7D,OAASC,EAAO,CACZ,MAAM,IAAIC,EACN,2CAA2CC,EAAiBF,CAAK,CAAC,EACtE,CACJ,CACJ,GAGAH,EAAQ,oBAA6BC,GAAUX,EAAA,sBAC3C,GAAI,CACA,IAAMgB,EAAeL,EAAM,QAAQ,MAC7BM,EAAgC,MAAMX,EAAsBU,CAAY,EAE9E,OAAQC,EAA8B,OAAQ,CAC1C,IAAK,qBACL,IAAK,qBAAsB,CACvBP,EAAQ,gBAAgB,gBAAgB,cAAc,EACtD,KACJ,CACA,IAAK,qBAAsB,CACvBA,EAAQ,gBAAgB,gBAAgB,cAAc,EACtD,KACJ,CACA,QACI,MAAM,IAAII,EACN,+BAA+BG,EAA8B,MAAM,EACvE,CAER,CACJ,OAASJ,EAAO,CACZ,MAAAH,EAAQ,gBAAgB,gBAAgB,cAAc,EAChD,IAAII,EAAa,6BAA6BC,EAAiBF,CAAK,CAAC,EAAE,CACjF,CACJ,GAEAH,EAAQ,SAAW,IAAM,CACrB,KAAK,gBAAgB,CACzB,EAEAA,EAAQ,MAAM,CAClB,CACJ,CAYO,gCACHR,EACAC,EACAe,EACAC,EACAd,EACmB,CACnB,MAAO,IAAYL,EAAA,sBACf,IAAMY,EAAyB,MAAMP,EAAeF,EAAQD,CAAQ,EAC9D,CAAE,GAAAkB,EAAI,KAAAC,EAAM,QAAAC,CAAQ,EAAIV,EAE9B,GAAI,qBAAQ,WACR,OAAO,WAAW,QACdQ,EACAC,EACA5B,EACAyB,EACAC,EACA,KACAG,EAAQ,IACRA,EAAQ,IACRA,EAAQ,KACZ,MAEA,OAAM,IAAIR,EAAa,gCAAgC,CAE/D,EACJ,CAEO,+BACHR,EACsD,CAEtD,OAAciB,GAAgBvB,EAAA,sBAC1B,GAAI,CACA,IAAMiB,EAAgC,MAAMX,EACxCiB,EAAY,kBAAkB,iBAAiB,KACnD,EAEA,OAAQN,EAA8B,OAAQ,CAC1C,IAAK,qBACL,IAAK,qBACL,IAAK,qBACD,MAEJ,QACI,MAAM,IAAIH,EACN,+BAA+BG,EAA8B,MAAM,EACvE,CAER,CACJ,OAASJ,EAAO,CACZ,MAAM,IAAIC,EAAa,6BAA6BC,EAAiBF,CAAK,CAAC,EAAE,CACjF,CACJ,EACJ,CACJ","names":["WalletType","determineApplePaySupport","getApplePayVersion","findMaxSupportedVersion","version","determineSamsungPaySupport","SessionError","message","getErrorAsString","error","SAMSUNG_PAY_SERVICE_ID","StitchWalletClientSdk","intialisationProperties","__publicField","onCancelPayment","determineApplePaySupport","determineSamsungPaySupport","__async","supportedWallets","currency","amount","label","verifyCallback","createPaymentCallback","version","getApplePayVersion","request","session","event","verifyCallbackResponse","error","SessionError","getErrorAsString","paymentToken","createPaymentCallbackResponse","callbackUrl","cancelUrl","id","href","encInfo","paymentData"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/utils/browser-support.ts","../src/utils/errors.ts","../src/utils/helpers.ts","../src/wallets/client.ts"],"sourcesContent":["export enum WalletType {\n ApplePay = 'APPLE_PAY',\n SamsungPay = 'SAMSUNG_PAY',\n GooglePay = 'GOOGLE_PAY',\n}\n\nexport type StitchTransactionState =\n | 'TransactionPending'\n | 'TransactionSuccess'\n | 'TransactionFailure';\n\nexport interface StitchTransaction {\n id: string;\n externalReference: string;\n quantity: number;\n currency: string;\n nonce: string;\n status: StitchTransactionState;\n statusReason?: string | null;\n interactionUrl?: string | null;\n}\nexport interface StitchWalletClientInitialisationProperties {\n onCancelPayment?: () => void;\n}\n\nexport type WalletPaySession = ApplePaySession | SamsungPaySession;\n\nexport interface ApplePaySession {\n epochTimestamp: number;\n expiresAt: number;\n merchantSessionIdentifier: string;\n nonce: string;\n merchantIdentifier: string;\n domainName: string;\n displayName: string;\n signature: string;\n operationalAnalyticsIdentifier: string;\n retries: number;\n pspId: string;\n}\nexport interface SamsungPaySession {\n id: string;\n href: string;\n encInfo: {\n mod: string;\n exp: string;\n keyId: string;\n };\n}\n\nexport type ApplePayVerifyCallback = (url: string) => Promise<WalletPaySession>;\nexport type SamsungPayVerifyCallback = (\n amount: number,\n currency: string,\n) => Promise<WalletPaySession>;\n\nexport type CreatePaymentCallback = (\n paymentToken:\n | ApplePayJS.ApplePayPaymentToken\n | google.payments.api.PaymentMethodTokenizationData['token'],\n) => Promise<CreatePaymentCallbackResponse>;\n\nexport interface CreatePaymentCallbackResponse {\n status: StitchTransaction['status'];\n}\n","interface SamsungPay {\n connect: (\n transactionId: string,\n href: string,\n serviceId: string,\n callbackUrl: string,\n cancelUrl: string,\n countryCode: string,\n // eslint-disable-next-line unicorn/prevent-abbreviations\n publicKeyMod: string,\n publicKeyExp: string,\n keyId: string,\n ) => void;\n}\n\ndeclare global {\n interface Window {\n ApplePaySession: ApplePaySession;\n SamsungPay: SamsungPay;\n }\n}\n\n/**\n * Determines whether Apple Pay is supported by the device.\n *\n * @returns {boolean} Whether Apple Pay is supported.\n */\nexport function determineApplePaySupport(): boolean {\n if (!window.ApplePaySession) {\n return false;\n }\n return ApplePaySession.canMakePayments();\n}\n\n/**\n * Determines the maximum supported Apple Pay version by the browser.\n *\n * @returns {number} The maximum supported version, or -1 if unsupported.\n */\nexport function getApplePayVersion(): number {\n const noSupportedVersion = -1;\n if (!window.ApplePaySession) {\n return noSupportedVersion;\n }\n\n const findMaxSupportedVersion = (version: number): number => {\n if (version === 0) return noSupportedVersion;\n if (ApplePaySession.supportsVersion(version)) {\n return version;\n }\n return findMaxSupportedVersion(version - 1);\n };\n\n return findMaxSupportedVersion(14);\n}\n\n/**\n * Determines whether Google Pay is supported on the device.\n *\n * @returns {boolean} Whether Google Pay is supported.\n */\nexport function determineGooglePaySupport(): boolean {\n return /android/i.test(navigator.userAgent);\n}\n\n/**\n * Determines whether Samsung Pay is supported by the browser.\n *\n * @returns {boolean} Whether Samsung Pay is supported.\n */\nexport function determineSamsungPaySupport(): boolean {\n console.log('determineSamsungPaySupport: PaymentRequest present:', window.PaymentRequest);\n console.log('determineSamsungPaySupport: SamsungPay present:', window.SamsungPay);\n console.log('determineSamsungPaySupport: UserAgent value:', navigator.userAgent);\n\n // Check at least that it is running on an Android device\n return determineGooglePaySupport();\n}\n","export class ApiError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\nexport class UserInputError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'UserInputError';\n }\n}\n\nexport class SessionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'SessionError';\n }\n}\n","/**\n * Converts any error object into a string representation.\n *\n * @param {unknown} error - The error object to convert.\n * @returns {string} String representation of the error.\n */\nexport const getErrorAsString = (error: unknown): string => {\n return error instanceof Error ? error.toString() : JSON.stringify(error);\n};\n","import {\n WalletType,\n type ApplePayVerifyCallback,\n type CreatePaymentCallback,\n type SamsungPaySession,\n type SamsungPayVerifyCallback,\n type StitchWalletClientInitialisationProperties,\n} from 'src/types';\nimport {\n determineApplePaySupport,\n determineGooglePaySupport,\n determineSamsungPaySupport,\n getApplePayVersion,\n} from 'src/utils/browser-support';\nimport { SessionError } from 'src/utils/errors';\nimport { getErrorAsString } from 'src/utils/helpers';\n\nconst SAMSUNG_PAY_SERVICE_ID = '9ba67dd8d5b247cfb3f76e';\n\n/**\n * Client-side SDK for handling Stitch wallet payments\n */\nexport class StitchWalletClientSdk {\n private readonly onCancelPayment: () => void;\n\n private applePayIsSupported: boolean;\n private samsungPayIsSupported: boolean;\n // eslint-disable-next-line @typescript-eslint/prefer-readonly\n private googlePayIsSupported: boolean;\n\n /**\n * Initializes a StitchWalletClientSdk instance\n *\n * @param {StitchWalletClientInitialisationProperties} initialisationProperties\n */\n constructor(initialisationProperties: StitchWalletClientInitialisationProperties) {\n const { onCancelPayment } = initialisationProperties;\n this.applePayIsSupported = determineApplePaySupport();\n this.samsungPayIsSupported = determineSamsungPaySupport();\n this.googlePayIsSupported = determineGooglePaySupport();\n this.onCancelPayment = onCancelPayment ?? (() => {});\n }\n\n /**\n * Returns a list of wallet payment methods supported on the device and/or browser\n *\n * @returns {Promise<WalletType[]>} Array of supported payment methods\n */\n public async supportedPaymentMethods(): Promise<WalletType[]> {\n const supportedWallets: WalletType[] = [];\n\n this.applePayIsSupported = determineApplePaySupport();\n if (this.applePayIsSupported) {\n supportedWallets.push(WalletType.ApplePay);\n }\n\n this.samsungPayIsSupported = determineSamsungPaySupport();\n if (this.samsungPayIsSupported) {\n supportedWallets.push(WalletType.SamsungPay);\n }\n\n if (this.googlePayIsSupported) {\n supportedWallets.push(WalletType.GooglePay);\n }\n\n return supportedWallets;\n }\n\n /**\n * Returns a onClick handler function for an Apple Pay session encapsulating merchant validation and payment creation\n *\n * @param {string} currency - Payment currency in ISO 4127 format e.g. ZAR.\n * @param {number} amount - Payment amount.\n * @param {string} label - Payment sheet label\n * @param {ApplePayVerifyCallback} verifyCallback - Callback for merchant validation.\n * @param {CreatePaymentCallback} createPaymentCallback - Callback for payment creation.\n * @returns {() => void} Function to handle Apple Pay button interaction\n */\n public onClickApplePaySessionHandler(\n currency: string,\n amount: number,\n label: string,\n verifyCallback: ApplePayVerifyCallback,\n createPaymentCallback: CreatePaymentCallback,\n ): () => void {\n const version = getApplePayVersion();\n\n return () => {\n const request: ApplePayJS.ApplePayPaymentRequest = {\n countryCode: 'ZA',\n currencyCode: currency,\n supportedNetworks: ['visa', 'masterCard'],\n merchantCapabilities: ['supports3DS'],\n total: {\n label,\n amount: amount.toString(),\n },\n };\n const session = new ApplePaySession(version, request);\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n session.onvalidatemerchant = async (event) => {\n try {\n const verifyCallbackResponse = await verifyCallback(event.validationURL);\n session.completeMerchantValidation(verifyCallbackResponse);\n } catch (error) {\n throw new SessionError(\n `Failed to complete merchant validation: ${getErrorAsString(error)}`,\n );\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n session.onpaymentauthorized = async (event) => {\n try {\n const paymentToken = event.payment.token;\n const createPaymentCallbackResponse = await createPaymentCallback(paymentToken);\n\n switch (createPaymentCallbackResponse.status) {\n case 'TransactionPending':\n case 'TransactionSuccess': {\n session.completePayment(ApplePaySession.STATUS_SUCCESS);\n break;\n }\n case 'TransactionFailure': {\n session.completePayment(ApplePaySession.STATUS_FAILURE);\n break;\n }\n default: {\n throw new SessionError(\n `Invalid transaction status: ${createPaymentCallbackResponse.status}`,\n );\n }\n }\n } catch (error) {\n session.completePayment(ApplePaySession.STATUS_FAILURE);\n throw new SessionError(`Failed to create payment: ${getErrorAsString(error)}`);\n }\n };\n // eslint-disable-next-line unicorn/prefer-add-event-listener\n session.oncancel = () => {\n this.onCancelPayment();\n };\n\n session.begin();\n };\n }\n\n /**\n * Returns a onClick handler function for a Samsung Pay session encapsulating payment verification and creation\n *\n * @param {string} currency - Payment currency in ISO 4127 format e.g. ZAR.\n * @param {number} amount - Payment amount.\n * @param {string} callbackUrl - Payment callback URL.\n * @param {number} cancelUrl - Payment cancellation URL.\n * @param {SamsungPayVerifyCallback} verifyCallback - Callback for payment verification.\n * @returns {() => void} Function to handle Apple Pay button interaction\n */\n public onClickSamsungPaySessionHandler(\n currency: string,\n amount: number,\n callbackUrl: string,\n cancelUrl: string,\n verifyCallback: SamsungPayVerifyCallback,\n ): () => Promise<void> {\n return async () => {\n const verifyCallbackResponse = await verifyCallback(amount, currency);\n const { id, href, encInfo } = verifyCallbackResponse as SamsungPaySession;\n\n if (window?.SamsungPay) {\n window.SamsungPay.connect(\n id,\n href,\n SAMSUNG_PAY_SERVICE_ID,\n callbackUrl,\n cancelUrl,\n 'uk',\n encInfo.mod,\n encInfo.exp,\n encInfo.keyId,\n );\n } else {\n throw new SessionError('Samsung Pay client unavailable');\n }\n };\n }\n\n public onClickGooglePaySessionHandler(\n createPaymentCallback: CreatePaymentCallback,\n ): (paymentData: google.payments.api.PaymentData) => void {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n return async (paymentData) => {\n try {\n const createPaymentCallbackResponse = await createPaymentCallback(\n paymentData.paymentMethodData.tokenizationData.token,\n );\n\n switch (createPaymentCallbackResponse.status) {\n case 'TransactionPending':\n case 'TransactionFailure':\n case 'TransactionSuccess': {\n break;\n }\n default: {\n throw new SessionError(\n `Invalid transaction status: ${createPaymentCallbackResponse.status}`,\n );\n }\n }\n } catch (error) {\n throw new SessionError(`Failed to create payment: ${getErrorAsString(error)}`);\n }\n };\n }\n}\n"],"mappings":";qXAAO,IAAKA,OACRA,EAAA,SAAW,YACXA,EAAA,WAAa,cACbA,EAAA,UAAY,aAHJA,OAAA,IC2BL,SAASC,GAAoC,CAChD,OAAK,OAAO,gBAGL,gBAAgB,gBAAgB,EAF5B,EAGf,CAOO,SAASC,GAA6B,CAEzC,GAAI,CAAC,OAAO,gBACR,MAAO,GAGX,IAAMC,EAA2BC,GACzBA,IAAY,EAAU,GACtB,gBAAgB,gBAAgBA,CAAO,EAChCA,EAEJD,EAAwBC,EAAU,CAAC,EAG9C,OAAOD,EAAwB,EAAE,CACrC,CAOO,SAASE,GAAqC,CACjD,MAAO,WAAW,KAAK,UAAU,SAAS,CAC9C,CAOO,SAASC,GAAsC,CAClD,eAAQ,IAAI,sDAAuD,OAAO,cAAc,EACxF,QAAQ,IAAI,kDAAmD,OAAO,UAAU,EAChF,QAAQ,IAAI,+CAAgD,UAAU,SAAS,EAGxED,EAA0B,CACrC,CC/DO,IAAME,EAAN,cAA2B,KAAM,CACpC,YAAYC,EAAiB,CACzB,MAAMA,CAAO,EACb,KAAK,KAAO,cAChB,CACJ,ECbO,IAAMC,EAAoBC,GACtBA,aAAiB,MAAQA,EAAM,SAAS,EAAI,KAAK,UAAUA,CAAK,ECU3E,IAAMC,EAAyB,yBAKlBC,EAAN,KAA4B,CAa/B,YAAYC,EAAsE,CAZlFC,EAAA,KAAiB,mBAEjBA,EAAA,KAAQ,uBACRA,EAAA,KAAQ,yBAERA,EAAA,KAAQ,wBAQJ,GAAM,CAAE,gBAAAC,CAAgB,EAAIF,EAC5B,KAAK,oBAAsBG,EAAyB,EACpD,KAAK,sBAAwBC,EAA2B,EACxD,KAAK,qBAAuBC,EAA0B,EACtD,KAAK,gBAAkBH,GAAA,KAAAA,EAAoB,IAAM,CAAC,CACtD,CAOa,yBAAiD,QAAAI,EAAA,sBAC1D,IAAMC,EAAiC,CAAC,EAExC,YAAK,oBAAsBJ,EAAyB,EAChD,KAAK,qBACLI,EAAiB,gBAAwB,EAG7C,KAAK,sBAAwBH,EAA2B,EACpD,KAAK,uBACLG,EAAiB,kBAA0B,EAG3C,KAAK,sBACLA,EAAiB,iBAAyB,EAGvCA,CACX,GAYO,8BACHC,EACAC,EACAC,EACAC,EACAC,EACU,CACV,IAAMC,EAAUC,EAAmB,EAEnC,MAAO,IAAM,CACT,IAAMC,EAA6C,CAC/C,YAAa,KACb,aAAcP,EACd,kBAAmB,CAAC,OAAQ,YAAY,EACxC,qBAAsB,CAAC,aAAa,EACpC,MAAO,CACH,MAAAE,EACA,OAAQD,EAAO,SAAS,CAC5B,CACJ,EACMO,EAAU,IAAI,gBAAgBH,EAASE,CAAO,EAEpDC,EAAQ,mBAA4BC,GAAUX,EAAA,sBAC1C,GAAI,CACA,IAAMY,EAAyB,MAAMP,EAAeM,EAAM,aAAa,EACvED,EAAQ,2BAA2BE,CAAsB,CAC7D,OAASC,EAAO,CACZ,MAAM,IAAIC,EACN,2CAA2CC,EAAiBF,CAAK,CAAC,EACtE,CACJ,CACJ,GAGAH,EAAQ,oBAA6BC,GAAUX,EAAA,sBAC3C,GAAI,CACA,IAAMgB,EAAeL,EAAM,QAAQ,MAC7BM,EAAgC,MAAMX,EAAsBU,CAAY,EAE9E,OAAQC,EAA8B,OAAQ,CAC1C,IAAK,qBACL,IAAK,qBAAsB,CACvBP,EAAQ,gBAAgB,gBAAgB,cAAc,EACtD,KACJ,CACA,IAAK,qBAAsB,CACvBA,EAAQ,gBAAgB,gBAAgB,cAAc,EACtD,KACJ,CACA,QACI,MAAM,IAAII,EACN,+BAA+BG,EAA8B,MAAM,EACvE,CAER,CACJ,OAASJ,EAAO,CACZ,MAAAH,EAAQ,gBAAgB,gBAAgB,cAAc,EAChD,IAAII,EAAa,6BAA6BC,EAAiBF,CAAK,CAAC,EAAE,CACjF,CACJ,GAEAH,EAAQ,SAAW,IAAM,CACrB,KAAK,gBAAgB,CACzB,EAEAA,EAAQ,MAAM,CAClB,CACJ,CAYO,gCACHR,EACAC,EACAe,EACAC,EACAd,EACmB,CACnB,MAAO,IAAYL,EAAA,sBACf,IAAMY,EAAyB,MAAMP,EAAeF,EAAQD,CAAQ,EAC9D,CAAE,GAAAkB,EAAI,KAAAC,EAAM,QAAAC,CAAQ,EAAIV,EAE9B,GAAI,qBAAQ,WACR,OAAO,WAAW,QACdQ,EACAC,EACA7B,EACA0B,EACAC,EACA,KACAG,EAAQ,IACRA,EAAQ,IACRA,EAAQ,KACZ,MAEA,OAAM,IAAIR,EAAa,gCAAgC,CAE/D,EACJ,CAEO,+BACHR,EACsD,CAEtD,OAAciB,GAAgBvB,EAAA,sBAC1B,GAAI,CACA,IAAMiB,EAAgC,MAAMX,EACxCiB,EAAY,kBAAkB,iBAAiB,KACnD,EAEA,OAAQN,EAA8B,OAAQ,CAC1C,IAAK,qBACL,IAAK,qBACL,IAAK,qBACD,MAEJ,QACI,MAAM,IAAIH,EACN,+BAA+BG,EAA8B,MAAM,EACvE,CAER,CACJ,OAASJ,EAAO,CACZ,MAAM,IAAIC,EAAa,6BAA6BC,EAAiBF,CAAK,CAAC,EAAE,CACjF,CACJ,EACJ,CACJ","names":["WalletType","determineApplePaySupport","getApplePayVersion","findMaxSupportedVersion","version","determineGooglePaySupport","determineSamsungPaySupport","SessionError","message","getErrorAsString","error","SAMSUNG_PAY_SERVICE_ID","StitchWalletClientSdk","initialisationProperties","__publicField","onCancelPayment","determineApplePaySupport","determineSamsungPaySupport","determineGooglePaySupport","__async","supportedWallets","currency","amount","label","verifyCallback","createPaymentCallback","version","getApplePayVersion","request","session","event","verifyCallbackResponse","error","SessionError","getErrorAsString","paymentToken","createPaymentCallbackResponse","callbackUrl","cancelUrl","id","href","encInfo","paymentData"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stitch-money/client",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "private": false,
5
5
  "description": "JavaScript package for the Stitch SDK",
6
6
  "repository": {
@@ -16,26 +16,19 @@
16
16
  "files": [
17
17
  "build"
18
18
  ],
19
- "scripts": {
20
- "build": "wireit",
21
- "lint": "eslint .",
22
- "prepublishOnly": "wireit",
23
- "test": "vitest",
24
- "typecheck": "tsc --noEmit"
25
- },
26
19
  "dependencies": {},
27
20
  "devDependencies": {
28
21
  "@types/applepayjs": "14.0.6",
29
22
  "@types/googlepay": "^0.7.6",
30
23
  "@types/uuid": "9.0.8",
31
24
  "@vitejs/plugin-react": "4.2.1",
32
- "eslint-config-stitch": "workspace:*",
33
25
  "jsdom": "24.0.0",
34
26
  "prop-types": "^15.8.1",
35
- "tsconfig-stitch": "workspace:*",
36
27
  "tsup": "8.0.2",
37
28
  "vite-tsconfig-paths": "4.3.1",
38
- "vitest": "1.3.1"
29
+ "vitest": "1.3.1",
30
+ "eslint-config-stitch": "0.0.0",
31
+ "tsconfig-stitch": "0.0.0"
39
32
  },
40
33
  "peerDependencies": {
41
34
  "uuid": "9.0.1"
@@ -56,5 +49,11 @@
56
49
  "build"
57
50
  ]
58
51
  }
52
+ },
53
+ "scripts": {
54
+ "build": "wireit",
55
+ "lint": "eslint .",
56
+ "test": "vitest",
57
+ "typecheck": "tsc --noEmit"
59
58
  }
60
- }
59
+ }