@stitch-money/client 1.0.0 → 1.1.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 +0 -9
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/package.json +1 -1
package/build/index.d.ts
CHANGED
|
@@ -14,7 +14,6 @@ interface StitchTransaction {
|
|
|
14
14
|
statusReason?: string | null;
|
|
15
15
|
}
|
|
16
16
|
interface StitchWalletClientInitialisationProperties {
|
|
17
|
-
merchantId: string;
|
|
18
17
|
onCancelPayment?: () => void;
|
|
19
18
|
}
|
|
20
19
|
type WalletPaySession = ApplePaySession | SamsungPaySession;
|
|
@@ -51,7 +50,6 @@ interface CreatePaymentCallbackResponse {
|
|
|
51
50
|
* Client-side SDK for handling Stitch wallet payments
|
|
52
51
|
*/
|
|
53
52
|
declare class StitchWalletClientSdk {
|
|
54
|
-
private readonly merchantId;
|
|
55
53
|
private readonly onCancelPayment;
|
|
56
54
|
private applePayIsSupported;
|
|
57
55
|
private samsungPayIsSupported;
|
|
@@ -62,13 +60,6 @@ declare class StitchWalletClientSdk {
|
|
|
62
60
|
* @param {StitchWalletClientInitialisationProperties} intialisationProperties
|
|
63
61
|
*/
|
|
64
62
|
constructor(intialisationProperties: StitchWalletClientInitialisationProperties);
|
|
65
|
-
/**
|
|
66
|
-
* Checks if the specified payment method is supported on the device and/or browser
|
|
67
|
-
*
|
|
68
|
-
* @param {WalletType} walletType - The enum type of wallet we are confirming support for.
|
|
69
|
-
* @returns {Promise<boolean>} True if the payment method is supported, otherwise false.
|
|
70
|
-
*/
|
|
71
|
-
isPaymentMethodSupported(walletType: WalletType): Promise<boolean>;
|
|
72
63
|
/**
|
|
73
64
|
* Returns a list of wallet payment methods supported on the device and/or browser
|
|
74
65
|
*
|
package/build/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client"
|
|
2
|
-
var
|
|
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};
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -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 merchantId: string; // Apple Pay Merchant ID\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 * Asynchronously checks for Apple Pay support, including payment capabilities and the maximum supported version.\n *\n * @param {string} merchantIdentifier - Merchant's Apple Pay identifier.\n * @returns {Promise<{\n * canMakePayments: boolean;\n * canMakePaymentsWithActiveCard: boolean;\n * maxSupportedVersion: number;\n * }>} An object indicating Apple Pay support details.\n */\nexport async function determineApplePaySupport(merchantIdentifier: string): Promise<{\n canMakePayments: boolean;\n canMakePaymentsWithActiveCard: boolean;\n maxSupportedVersion: number;\n}> {\n if (!window.ApplePaySession) {\n return {\n canMakePayments: false,\n canMakePaymentsWithActiveCard: false,\n maxSupportedVersion: getApplePayVersion(),\n };\n }\n const canMakePayments = ApplePaySession.canMakePayments();\n const canMakePaymentsWithActiveCard =\n await ApplePaySession.canMakePaymentsWithActiveCard(merchantIdentifier);\n return {\n canMakePayments,\n canMakePaymentsWithActiveCard,\n maxSupportedVersion: getApplePayVersion(),\n };\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, UserInputError } 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 merchantId: string;\n private readonly onCancelPayment: () => void;\n\n private applePayIsSupported: boolean;\n private samsungPayIsSupported: boolean;\n private googlePayIsSupported: boolean;\n\n /**\n * Initializes a StitchWalletClientSdk instance\n *\n * @param {StitchWalletClientInitialisationProperties} intialisationProperties\n */\n constructor(intialisationProperties: StitchWalletClientInitialisationProperties) {\n const { merchantId, onCancelPayment } = intialisationProperties;\n this.applePayIsSupported = false;\n this.samsungPayIsSupported = determineSamsungPaySupport();\n this.googlePayIsSupported = true;\n this.merchantId = merchantId;\n this.onCancelPayment = onCancelPayment ?? (() => {});\n }\n\n /**\n * Checks if the specified payment method is supported on the device and/or browser\n *\n * @param {WalletType} walletType - The enum type of wallet we are confirming support for.\n * @returns {Promise<boolean>} True if the payment method is supported, otherwise false.\n */\n public async isPaymentMethodSupported(walletType: WalletType): Promise<boolean> {\n switch (walletType) {\n case WalletType.ApplePay: {\n const applePaySupport = await determineApplePaySupport(this.merchantId);\n this.applePayIsSupported = applePaySupport.canMakePayments;\n return this.applePayIsSupported;\n }\n case WalletType.SamsungPay: {\n this.samsungPayIsSupported = determineSamsungPaySupport();\n return this.samsungPayIsSupported;\n }\n case WalletType.GooglePay: {\n this.googlePayIsSupported = true;\n return this.googlePayIsSupported;\n }\n default: {\n throw new UserInputError(`Unsupported wallet: ${walletType}`);\n }\n }\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 const applePaySupport = await determineApplePaySupport(this.merchantId);\n this.applePayIsSupported = applePaySupport.canMakePayments;\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 if (!this.applePayIsSupported) {\n throw new SessionError('Apple Pay is not supported on this device');\n }\n\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":"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","names":["WalletType","determineApplePaySupport","merchantIdentifier","__async","getApplePayVersion","canMakePayments","canMakePaymentsWithActiveCard","findMaxSupportedVersion","version","determineSamsungPaySupport","UserInputError","message","SessionError","getErrorAsString","error","SAMSUNG_PAY_SERVICE_ID","StitchWalletClientSdk","intialisationProperties","__publicField","merchantId","onCancelPayment","determineSamsungPaySupport","walletType","__async","applePaySupport","determineApplePaySupport","UserInputError","supportedWallets","currency","amount","label","verifyCallback","createPaymentCallback","SessionError","version","getApplePayVersion","request","session","event","verifyCallbackResponse","error","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}\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":"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","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"]}
|