diff --git a/android/build.gradle b/android/build.gradle index 6840f0cf..456bbc48 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -28,7 +28,7 @@ def getExtOrIntegerDefault(name) { return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['StripeTerminalReactNative_' + name]).toInteger() } -def terminalAndroidSdkVersion = '3.5.0' +def terminalAndroidSdkVersion = '3.6.0' def reactNativeSdkVersion = getVersionFromNpm() android { diff --git a/android/src/main/java/com/stripeterminalreactnative/StripeTerminalReactNativeModule.kt b/android/src/main/java/com/stripeterminalreactnative/StripeTerminalReactNativeModule.kt index af06b887..401dec92 100644 --- a/android/src/main/java/com/stripeterminalreactnative/StripeTerminalReactNativeModule.kt +++ b/android/src/main/java/com/stripeterminalreactnative/StripeTerminalReactNativeModule.kt @@ -23,6 +23,7 @@ import com.stripe.stripeterminal.external.models.CardPresentRoutingOptionParamet import com.stripe.stripeterminal.external.models.Cart import com.stripe.stripeterminal.external.models.CollectConfiguration import com.stripe.stripeterminal.external.models.CollectInputsParameters +import com.stripe.stripeterminal.external.models.ConnectionStatus import com.stripe.stripeterminal.external.models.CreateConfiguration import com.stripe.stripeterminal.external.models.DiscoveryConfiguration import com.stripe.stripeterminal.external.models.EmailInput @@ -796,6 +797,18 @@ class StripeTerminalReactNativeModule(reactContext: ReactApplicationContext) : promise.resolve(mapFromOfflineStatus(terminal.offlineStatus)) } + @ReactMethod + @Suppress("unused") + fun getPaymentStatus(promise: Promise) { + promise.resolve(mapFromPaymentStatus(terminal.paymentStatus)) + } + + @ReactMethod + @Suppress("unused") + fun getConnectionStatus(promise: Promise) { + promise.resolve(mapFromConnectionStatus(terminal.connectionStatus)) + } + @ReactMethod @Suppress("unused") fun getReaderSettings(promise: Promise) { diff --git a/bitrise.yml b/bitrise.yml index 1fa46c3e..436ec634 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -96,7 +96,7 @@ workflows: set -e # This is a terrible hack, as I haven't worked out how Bitrise's `pod install` step interacts with the rbenv set in this app. You definitely shouldn't copy this. cd dev-app/ios && asdf install ruby 3.2.3 && bundle install && \ - gem install cocoapods -v 1.14.2 && pod install && cd - && \ + gem install cocoapods -v 1.15.2 && pod install && cd - && \ npm rebuild detox echo "Checking for diffs in pod lockfile, if this fails please ensure all dependencies are up to date" && \ git diff --exit-code diff --git a/dev-app/ios/Podfile.lock b/dev-app/ios/Podfile.lock index 901370b5..ca19886d 100644 --- a/dev-app/ios/Podfile.lock +++ b/dev-app/ios/Podfile.lock @@ -440,8 +440,8 @@ PODS: - SocketRocket (0.6.1) - stripe-terminal-react-native (0.0.1-beta.18): - React-Core - - StripeTerminal (~> 3.5.0) - - StripeTerminal (3.5.0) + - StripeTerminal (~> 3.6.0) + - StripeTerminal (3.6.0) - Yoga (1.14.0) DEPENDENCIES: @@ -640,8 +640,8 @@ SPEC CHECKSUMS: RNGestureHandler: 32a01c29ecc9bb0b5bf7bc0a33547f61b4dc2741 RNScreens: 3c2d122f5e08c192e254c510b212306da97d2581 SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 - stripe-terminal-react-native: d4d8536646e1d16ae8a906867e79107b02e8fc1f - StripeTerminal: 107cb1815738accbaa54179411cd916ed129b044 + stripe-terminal-react-native: ca2785cc6ec7efc9b2a4a5b7fdb6ef9b7084ce24 + StripeTerminal: d480f58ed3a170695a92954a0f64e97383983a26 Yoga: 4c3aa327e4a6a23eeacd71f61c81df1bcdf677d5 PODFILE CHECKSUM: 8b6a9ec02d405ae261b816f227c75d2138b656d5 diff --git a/dev-app/src/AppContext.ts b/dev-app/src/AppContext.ts index 876aa436..28cd9ad9 100644 --- a/dev-app/src/AppContext.ts +++ b/dev-app/src/AppContext.ts @@ -13,6 +13,8 @@ export const AppContext = React.createContext({ setLastSuccessfulChargeId: (_id) => null, lastSuccessfulPaymentIntentId: null, setLastSuccessfulPaymentIntentId: (_id) => null, + lastSuccessfulAmount: null, + setLastSuccessfulAmount: (_a) => null, autoReconnectOnUnexpectedDisconnect: false, setAutoReconnectOnUnexpectedDisconnect: (_b) => null, cachedLocations: [], diff --git a/dev-app/src/Root.tsx b/dev-app/src/Root.tsx index 2d368c54..8fc2ec88 100644 --- a/dev-app/src/Root.tsx +++ b/dev-app/src/Root.tsx @@ -21,6 +21,9 @@ export default function Root() { >(null); const [lastSuccessfulPaymentIntentId, setLastSuccessfulPaymentIntentId] = useState(null); + const [lastSuccessfulAmount, setLastSuccessfulAmount] = useState< + string | null + >(null); const [ autoReconnectOnUnexpectedDisconnect, setAutoReconnectOnUnexpectedDisconnect, @@ -96,6 +99,8 @@ export default function Root() { setLastSuccessfulPaymentIntentId: (id) => setLastSuccessfulPaymentIntentId(id), lastSuccessfulPaymentIntentId, + setLastSuccessfulAmount: (a) => setLastSuccessfulAmount(a), + lastSuccessfulAmount, autoReconnectOnUnexpectedDisconnect, setAutoReconnectOnUnexpectedDisconnect: (b) => setAutoReconnectOnUnexpectedDisconnect(b), diff --git a/dev-app/src/screens/CollectCardPaymentScreen.tsx b/dev-app/src/screens/CollectCardPaymentScreen.tsx index bd8e1c13..20ba4f43 100644 --- a/dev-app/src/screens/CollectCardPaymentScreen.tsx +++ b/dev-app/src/screens/CollectCardPaymentScreen.tsx @@ -59,6 +59,7 @@ export default function CollectCardPaymentScreen() { api, setLastSuccessfulChargeId, setLastSuccessfulPaymentIntentId, + setLastSuccessfulAmount, account, } = useContext(AppContext); @@ -478,6 +479,7 @@ export default function CollectCardPaymentScreen() { if (paymentIntent?.charges[0]?.id) { setLastSuccessfulChargeId(paymentIntent.charges[0].id); setLastSuccessfulPaymentIntentId(paymentIntent.id); + setLastSuccessfulAmount(paymentIntent.amount.toString()); } if (paymentIntent?.status === 'succeeded') { diff --git a/dev-app/src/screens/RefundPaymentScreen.tsx b/dev-app/src/screens/RefundPaymentScreen.tsx index 6a58c070..a2a2d152 100644 --- a/dev-app/src/screens/RefundPaymentScreen.tsx +++ b/dev-app/src/screens/RefundPaymentScreen.tsx @@ -21,8 +21,11 @@ import type { RouteParamList } from '../App'; import { Picker } from '@react-native-picker/picker'; export default function RefundPaymentScreen() { - const { lastSuccessfulChargeId, lastSuccessfulPaymentIntentId } = - useContext(AppContext); + const { + lastSuccessfulAmount, + lastSuccessfulChargeId, + lastSuccessfulPaymentIntentId, + } = useContext(AppContext); const [inputValues, setInputValues] = useState<{ chargeId: string; paymentIntentId: string; @@ -34,7 +37,7 @@ export default function RefundPaymentScreen() { }>({ chargeId: lastSuccessfulChargeId || '', paymentIntentId: lastSuccessfulPaymentIntentId || '', - amount: '100', + amount: lastSuccessfulAmount || '', currency: 'CAD', refundApplicationFee: false, reverseTransfer: false, diff --git a/dev-app/src/types.ts b/dev-app/src/types.ts index 64f81643..9fa2adcb 100644 --- a/dev-app/src/types.ts +++ b/dev-app/src/types.ts @@ -16,6 +16,8 @@ export type IAppContext = { setLastSuccessfulChargeId: (id: string) => void; lastSuccessfulPaymentIntentId: string | null; setLastSuccessfulPaymentIntentId: (id: string) => void; + lastSuccessfulAmount: string | null; + setLastSuccessfulAmount: (amount: string) => void; autoReconnectOnUnexpectedDisconnect: boolean | false; setAutoReconnectOnUnexpectedDisconnect: (b: boolean) => void; cachedLocations: Array; diff --git a/ios/StripeTerminalReactNative.m b/ios/StripeTerminalReactNative.m index d14803aa..b9b3211a 100644 --- a/ios/StripeTerminalReactNative.m +++ b/ios/StripeTerminalReactNative.m @@ -199,6 +199,16 @@ @interface RCT_EXTERN_MODULE(StripeTerminalReactNative, RCTEventEmitter) rejecter: (RCTPromiseRejectBlock)reject ) +RCT_EXTERN_METHOD( + getPaymentStatus:(RCTPromiseResolveBlock)resolve + rejecter: (RCTPromiseRejectBlock)reject + ) + +RCT_EXTERN_METHOD( + getConnectionStatus:(RCTPromiseResolveBlock)resolve + rejecter: (RCTPromiseRejectBlock)reject + ) + RCT_EXTERN_METHOD( collectInputs:(NSDictionary *)params resolver: (RCTPromiseResolveBlock)resolve diff --git a/ios/StripeTerminalReactNative.swift b/ios/StripeTerminalReactNative.swift index 425a7f46..1f479412 100644 --- a/ios/StripeTerminalReactNative.swift +++ b/ios/StripeTerminalReactNative.swift @@ -954,6 +954,20 @@ class StripeTerminalReactNative: RCTEventEmitter, DiscoveryDelegate, BluetoothRe resolve(result) } + + @objc(getPaymentStatus:rejecter:) + func getPaymentStatus(resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + let result = Mappers.mapFromPaymentStatus(Terminal.shared.paymentStatus) + + resolve(result) + } + + @objc(getConnectionStatus:rejecter:) + func getConnectionStatus(resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + let result = Mappers.mapFromConnectionStatus(Terminal.shared.connectionStatus) + + resolve(result) + } @objc(collectInputs:resolver:rejecter:) func collectInputs(_ params: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { diff --git a/src/StripeTerminalSdk.tsx b/src/StripeTerminalSdk.tsx index 48f98689..8fcc4f2e 100644 --- a/src/StripeTerminalSdk.tsx +++ b/src/StripeTerminalSdk.tsx @@ -33,6 +33,8 @@ import type { OfflineStatus, CollectInputsParameters, CollectInputsResults, + PaymentStatus, + ConnectionStatus, } from './types'; const { StripeTerminalReactNative } = NativeModules; @@ -145,6 +147,8 @@ export interface StripeTerminalSdkType { error?: StripeError; }>; getOfflineStatus(): Promise; + getPaymentStatus(): Promise; + getConnectionStatus(): Promise; getReaderSettings(): Promise; setReaderSettings( params: Reader.ReaderSettingsParameters diff --git a/src/__tests__/__snapshots__/functions.test.ts.snap b/src/__tests__/__snapshots__/functions.test.ts.snap index 08f1e188..913c3b00 100644 --- a/src/__tests__/__snapshots__/functions.test.ts.snap +++ b/src/__tests__/__snapshots__/functions.test.ts.snap @@ -29,8 +29,10 @@ Object { "createSetupIntent": [Function], "disconnectReader": [Function], "discoverReaders": [Function], + "getConnectionStatus": [Function], "getLocations": [Function], "getOfflineStatus": [Function], + "getPaymentStatus": [Function], "getReaderSettings": [Function], "initialize": [Function], "installAvailableUpdate": [Function], diff --git a/src/functions.ts b/src/functions.ts index ce3061ac..4058be7b 100644 --- a/src/functions.ts +++ b/src/functions.ts @@ -34,6 +34,8 @@ import type { OfflineStatus, CollectInputsParameters, CollectInputsResults, + PaymentStatus, + ConnectionStatus, } from './types'; export async function initialize( @@ -774,6 +776,32 @@ export async function getOfflineStatus(): Promise { }, 'getOfflineStatus')(); } +export async function getPaymentStatus(): Promise { + return Logger.traceSdkMethod(async () => { + try { + const paymentStatus = await StripeTerminalSdk.getPaymentStatus(); + return paymentStatus; + } catch (error) { + return { + error: error as any, + }; + } + }, 'getPaymentStatus')(); +} + +export async function getConnectionStatus(): Promise { + return Logger.traceSdkMethod(async () => { + try { + const connectionStatus = await StripeTerminalSdk.getConnectionStatus(); + return connectionStatus; + } catch (error) { + return { + error: error as any, + }; + } + }, 'getConnectionStatus')(); +} + export async function getReaderSettings(): Promise { return Logger.traceSdkMethod(async () => { try { diff --git a/src/hooks/__tests__/__snapshots__/useStripeTerminal.test.tsx.snap b/src/hooks/__tests__/__snapshots__/useStripeTerminal.test.tsx.snap index 69847800..cbe939a2 100644 --- a/src/hooks/__tests__/__snapshots__/useStripeTerminal.test.tsx.snap +++ b/src/hooks/__tests__/__snapshots__/useStripeTerminal.test.tsx.snap @@ -33,8 +33,10 @@ Object { "discoverReaders": [Function], "discoveredReaders": Array [], "emitter": undefined, + "getConnectionStatus": [Function], "getLocations": [Function], "getOfflineStatus": [Function], + "getPaymentStatus": [Function], "getReaderSettings": [Function], "initialize": [Function], "installAvailableUpdate": [Function], diff --git a/src/hooks/useStripeTerminal.tsx b/src/hooks/useStripeTerminal.tsx index de9a0892..df73b754 100644 --- a/src/hooks/useStripeTerminal.tsx +++ b/src/hooks/useStripeTerminal.tsx @@ -64,6 +64,8 @@ import { cancelCollectInputs, cancelReaderReconnection, supportsReadersOfType, + getPaymentStatus, + getConnectionStatus, } from '../functions'; import { StripeTerminalContext } from '../components/StripeTerminalContext'; import { useListener } from './useListener'; @@ -906,6 +908,24 @@ export function useStripeTerminal(props?: Props) { return response; }, [_isInitialized]); + const _getPaymentStatus = useCallback(async () => { + if (!_isInitialized()) { + console.error(NOT_INITIALIZED_ERROR_MESSAGE); + throw Error(NOT_INITIALIZED_ERROR_MESSAGE); + } + const response = await getPaymentStatus(); + return response; + }, [_isInitialized]); + + const _getConnectionStatus = useCallback(async () => { + if (!_isInitialized()) { + console.error(NOT_INITIALIZED_ERROR_MESSAGE); + throw Error(NOT_INITIALIZED_ERROR_MESSAGE); + } + const response = await getConnectionStatus(); + return response; + }, [_isInitialized]); + const _getReaderSettings = useCallback(async () => { if (!_isInitialized()) { console.error(NOT_INITIALIZED_ERROR_MESSAGE); @@ -1026,6 +1046,8 @@ export function useStripeTerminal(props?: Props) { connectLocalMobileReader: _connectLocalMobileReader, setSimulatedCard: _setSimulatedCard, getOfflineStatus: _getOfflineStatus, + getPaymentStatus: _getPaymentStatus, + getConnectionStatus: _getConnectionStatus, getReaderSettings: _getReaderSettings, setReaderSettings: _setReaderSettings, collectInputs: _collectInputs, diff --git a/src/types/index.ts b/src/types/index.ts index 105adaed..5071e0de 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -315,6 +315,8 @@ export type OfflineStatus = { export type ReaderEvent = 'cardInserted' | 'cardRemoved'; +export type ConnectionStatus = 'notConnected' | 'connecting' | 'connected'; + /** * @ignore */ diff --git a/stripe-terminal-react-native.podspec b/stripe-terminal-react-native.podspec index 531aa9d9..9bf57442 100644 --- a/stripe-terminal-react-native.podspec +++ b/stripe-terminal-react-native.podspec @@ -16,5 +16,5 @@ Pod::Spec.new do |s| s.source_files = 'ios/**/*.{h,m,mm,swift}' s.dependency 'React-Core' - s.dependency 'StripeTerminal', '~> 3.5.0' + s.dependency 'StripeTerminal', '~> 3.6.0' end