diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/TerminalPlugin.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/TerminalPlugin.kt index d582dd4..fee282a 100644 --- a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/TerminalPlugin.kt +++ b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/TerminalPlugin.kt @@ -52,9 +52,9 @@ import mek.stripeterminal.api.TerminalExceptionCodeApi import mek.stripeterminal.api.TerminalHandlersApi import mek.stripeterminal.api.TerminalPlatformApi import mek.stripeterminal.api.TippingConfigurationApi -import mek.stripeterminal.api.toApi -import mek.stripeterminal.api.toHost -import mek.stripeterminal.api.toPlatformError +import mek.stripeterminal.mappings.toApi +import mek.stripeterminal.mappings.toHost +import mek.stripeterminal.mappings.toPlatformError import mek.stripeterminal.plugin.DiscoverReadersSubject import mek.stripeterminal.plugin.ReaderDelegatePlugin import mek.stripeterminal.plugin.ReaderReconnectionListenerPlugin diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/api/ToApiExtensions.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/api/ToApiExtensions.kt deleted file mode 100644 index a48e11e..0000000 --- a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/api/ToApiExtensions.kt +++ /dev/null @@ -1,571 +0,0 @@ -package mek.stripeterminal.api - -import com.stripe.stripeterminal.external.models.Address -import com.stripe.stripeterminal.external.models.BatteryStatus -import com.stripe.stripeterminal.external.models.CardNetworks -import com.stripe.stripeterminal.external.models.CardPresentDetails -import com.stripe.stripeterminal.external.models.ConnectionStatus -import com.stripe.stripeterminal.external.models.DeviceType -import com.stripe.stripeterminal.external.models.IncrementalAuthorizationStatus -import com.stripe.stripeterminal.external.models.Location -import com.stripe.stripeterminal.external.models.LocationStatus -import com.stripe.stripeterminal.external.models.PaymentIntent -import com.stripe.stripeterminal.external.models.PaymentIntentStatus -import com.stripe.stripeterminal.external.models.PaymentMethodDetails -import com.stripe.stripeterminal.external.models.PaymentStatus -import com.stripe.stripeterminal.external.models.Reader -import com.stripe.stripeterminal.external.models.ReaderDisplayMessage -import com.stripe.stripeterminal.external.models.ReaderEvent -import com.stripe.stripeterminal.external.models.ReaderInputOptions -import com.stripe.stripeterminal.external.models.ReaderSoftwareUpdate -import com.stripe.stripeterminal.external.models.ReceiptDetails -import com.stripe.stripeterminal.external.models.Refund -import com.stripe.stripeterminal.external.models.SetupAttempt -import com.stripe.stripeterminal.external.models.SetupAttemptStatus -import com.stripe.stripeterminal.external.models.SetupIntent -import com.stripe.stripeterminal.external.models.SetupIntentCardPresentDetails -import com.stripe.stripeterminal.external.models.SetupIntentPaymentMethodDetails -import com.stripe.stripeterminal.external.models.SetupIntentStatus -import com.stripe.stripeterminal.external.models.SetupIntentUsage -import com.stripe.stripeterminal.external.models.TerminalException -import com.stripe.stripeterminal.external.models.TerminalException.TerminalErrorCode -import mek.stripeterminal.mappings.toApi -import mek.stripeterminal.toHashMap - -fun TerminalException.toPlatformError(): PlatformError { - return toApi().toPlatformError() -} - -fun TerminalExceptionApi.toPlatformError(): PlatformError { - return PlatformError(code = "mek_stripe_terminal", message = null, details = serialize()) -} - -fun TerminalException.toApi(): TerminalExceptionApi { - val code = errorCode.toApiCode() - return TerminalExceptionApi( - code = code ?: TerminalExceptionCodeApi.UNKNOWN, - message = errorMessage, - stackTrace = stackTraceToString(), - paymentIntent = paymentIntent?.toApi(), - apiError = apiError?.toString(), - ) -} - -private fun TerminalErrorCode.toApiCode(): TerminalExceptionCodeApi? { - return when (this) { - TerminalErrorCode.CANCEL_FAILED -> TerminalExceptionCodeApi.CANCEL_FAILED - TerminalErrorCode.NOT_CONNECTED_TO_READER -> TerminalExceptionCodeApi.NOT_CONNECTED_TO_READER - TerminalErrorCode.ALREADY_CONNECTED_TO_READER -> - TerminalExceptionCodeApi.ALREADY_CONNECTED_TO_READER - TerminalErrorCode.BLUETOOTH_PERMISSION_DENIED -> - TerminalExceptionCodeApi.BLUETOOTH_PERMISSION_DENIED - TerminalErrorCode.CONFIRM_INVALID_PAYMENT_INTENT -> - TerminalExceptionCodeApi.CONFIRM_INVALID_PAYMENT_INTENT - TerminalErrorCode.INVALID_CLIENT_SECRET -> TerminalExceptionCodeApi.INVALID_CLIENT_SECRET - TerminalErrorCode.UNSUPPORTED_OPERATION -> TerminalExceptionCodeApi.UNSUPPORTED_OPERATION - TerminalErrorCode.UNEXPECTED_OPERATION -> TerminalExceptionCodeApi.UNEXPECTED_OPERATION - TerminalErrorCode.UNSUPPORTED_SDK -> TerminalExceptionCodeApi.UNSUPPORTED_SDK - TerminalErrorCode.USB_PERMISSION_DENIED -> TerminalExceptionCodeApi.USB_PERMISSION_DENIED - TerminalErrorCode.MISSING_PREREQUISITE -> null - TerminalErrorCode.MISSING_REQUIRED_PARAMETER -> TerminalExceptionCodeApi.INVALID_PARAMETER - TerminalErrorCode.INVALID_REQUIRED_PARAMETER -> - TerminalExceptionCodeApi.INVALID_REQUIRED_PARAMETER - TerminalErrorCode.INVALID_TIP_PARAMETER -> TerminalExceptionCodeApi.INVALID_TIP_PARAMETER - TerminalErrorCode.LOCAL_MOBILE_LIBRARY_NOT_INCLUDED -> null - TerminalErrorCode.LOCAL_MOBILE_UNSUPPORTED_DEVICE -> - TerminalExceptionCodeApi.LOCAL_MOBILE_UNSUPPORTED_DEVICE - TerminalErrorCode.LOCAL_MOBILE_UNSUPPORTED_ANDROID_VERSION -> - TerminalExceptionCodeApi.LOCAL_MOBILE_UNSUPPORTED_OPERATING_SYSTEM_VERSION - TerminalErrorCode.LOCAL_MOBILE_DEVICE_TAMPERED -> - TerminalExceptionCodeApi.LOCAL_MOBILE_DEVICE_TAMPERED - TerminalErrorCode.LOCAL_MOBILE_DEBUG_NOT_SUPPORTED -> - TerminalExceptionCodeApi.LOCAL_MOBILE_DEBUG_NOT_SUPPORTED - TerminalErrorCode.OFFLINE_MODE_UNSUPPORTED_ANDROID_VERSION -> - TerminalExceptionCodeApi.OFFLINE_MODE_UNSUPPORTED_OPERATING_SYSTEM_VERSION - TerminalErrorCode.CANCELED -> TerminalExceptionCodeApi.CANCELED - TerminalErrorCode.LOCATION_SERVICES_DISABLED -> - TerminalExceptionCodeApi.LOCATION_SERVICES_DISABLED - TerminalErrorCode.BLUETOOTH_SCAN_TIMED_OUT -> TerminalExceptionCodeApi.BLUETOOTH_SCAN_TIMED_OUT - TerminalErrorCode.BLUETOOTH_LOW_ENERGY_UNSUPPORTED -> - TerminalExceptionCodeApi.BLUETOOTH_LOW_ENERGY_UNSUPPORTED - TerminalErrorCode.READER_SOFTWARE_UPDATE_FAILED_BATTERY_LOW -> - TerminalExceptionCodeApi.READER_SOFTWARE_UPDATE_FAILED_BATTERY_LOW - TerminalErrorCode.READER_SOFTWARE_UPDATE_FAILED_INTERRUPTED -> - TerminalExceptionCodeApi.READER_SOFTWARE_UPDATE_FAILED_INTERRUPTED - TerminalErrorCode.CARD_INSERT_NOT_READ -> TerminalExceptionCodeApi.CARD_INSERT_NOT_READ - TerminalErrorCode.CARD_SWIPE_NOT_READ -> TerminalExceptionCodeApi.CARD_SWIPE_NOT_READ - TerminalErrorCode.CARD_READ_TIMED_OUT -> TerminalExceptionCodeApi.CARD_READ_TIMED_OUT - TerminalErrorCode.CARD_REMOVED -> TerminalExceptionCodeApi.CARD_REMOVED - TerminalErrorCode.CUSTOMER_CONSENT_REQUIRED -> - TerminalExceptionCodeApi.CUSTOMER_CONSENT_REQUIRED - TerminalErrorCode.CARD_LEFT_IN_READER -> TerminalExceptionCodeApi.CARD_LEFT_IN_READER - TerminalErrorCode.USB_DISCOVERY_TIMED_OUT -> TerminalExceptionCodeApi.USB_DISCOVERY_TIMED_OUT - TerminalErrorCode.FEATURE_NOT_ENABLED_ON_ACCOUNT -> - TerminalExceptionCodeApi.FEATURE_NOT_ENABLED_ON_ACCOUNT - TerminalErrorCode.READER_BUSY -> TerminalExceptionCodeApi.READER_BUSY - TerminalErrorCode.READER_COMMUNICATION_ERROR -> - TerminalExceptionCodeApi.READER_COMMUNICATION_ERROR - TerminalErrorCode.BLUETOOTH_ERROR -> TerminalExceptionCodeApi.BLUETOOTH_ERROR - TerminalErrorCode.BLUETOOTH_DISCONNECTED -> TerminalExceptionCodeApi.BLUETOOTH_DISCONNECTED - TerminalErrorCode.BLUETOOTH_RECONNECT_STARTED -> - TerminalExceptionCodeApi.BLUETOOTH_RECONNECT_STARTED - TerminalErrorCode.USB_DISCONNECTED -> TerminalExceptionCodeApi.USB_DISCONNECTED - TerminalErrorCode.USB_RECONNECT_STARTED -> TerminalExceptionCodeApi.USB_RECONNECT_STARTED - TerminalErrorCode.READER_CONNECTED_TO_ANOTHER_DEVICE -> - TerminalExceptionCodeApi.READER_CONNECTED_TO_ANOTHER_DEVICE - TerminalErrorCode.READER_SOFTWARE_UPDATE_FAILED -> - TerminalExceptionCodeApi.READER_SOFTWARE_UPDATE_FAILED - TerminalErrorCode.READER_SOFTWARE_UPDATE_FAILED_READER_ERROR -> - TerminalExceptionCodeApi.READER_SOFTWARE_UPDATE_FAILED_READER_ERROR - TerminalErrorCode.READER_SOFTWARE_UPDATE_FAILED_SERVER_ERROR -> - TerminalExceptionCodeApi.READER_SOFTWARE_UPDATE_FAILED_SERVER_ERROR - TerminalErrorCode.LOCAL_MOBILE_NFC_DISABLED -> TerminalExceptionCodeApi.NFC_DISABLED - TerminalErrorCode.UNSUPPORTED_READER_VERSION -> - TerminalExceptionCodeApi.UNSUPPORTED_READER_VERSION - TerminalErrorCode.UNEXPECTED_SDK_ERROR -> TerminalExceptionCodeApi.UNEXPECTED_SDK_ERROR - TerminalErrorCode.DECLINED_BY_STRIPE_API -> TerminalExceptionCodeApi.DECLINED_BY_STRIPE_API - TerminalErrorCode.DECLINED_BY_READER -> TerminalExceptionCodeApi.DECLINED_BY_READER - TerminalErrorCode.REQUEST_TIMED_OUT -> TerminalExceptionCodeApi.REQUEST_TIMED_OUT - TerminalErrorCode.STRIPE_API_CONNECTION_ERROR -> - TerminalExceptionCodeApi.STRIPE_API_CONNECTION_ERROR - TerminalErrorCode.STRIPE_API_ERROR -> TerminalExceptionCodeApi.STRIPE_API_ERROR - TerminalErrorCode.STRIPE_API_RESPONSE_DECODING_ERROR -> - TerminalExceptionCodeApi.STRIPE_API_RESPONSE_DECODING_ERROR - TerminalErrorCode.CONNECTION_TOKEN_PROVIDER_ERROR -> - TerminalExceptionCodeApi.CONNECTION_TOKEN_PROVIDER_ERROR - TerminalErrorCode.SESSION_EXPIRED -> TerminalExceptionCodeApi.SESSION_EXPIRED - TerminalErrorCode.ANDROID_API_LEVEL_ERROR -> - TerminalExceptionCodeApi.UNSUPPORTED_MOBILE_DEVICE_CONFIGURATION - TerminalErrorCode.AMOUNT_EXCEEDS_MAX_OFFLINE_AMOUNT -> - TerminalExceptionCodeApi.AMOUNT_EXCEEDS_MAX_OFFLINE_AMOUNT - TerminalErrorCode.OFFLINE_PAYMENTS_DATABASE_TOO_LARGE -> - TerminalExceptionCodeApi.OFFLINE_PAYMENTS_DATABASE_TOO_LARGE - TerminalErrorCode.READER_CONNECTION_NOT_AVAILABLE_OFFLINE -> - TerminalExceptionCodeApi.READER_CONNECTION_NOT_AVAILABLE_OFFLINE - TerminalErrorCode.LOCATION_CONNECTION_NOT_AVAILABLE_OFFLINE -> - TerminalExceptionCodeApi.LOCATION_CONNECTION_NOT_AVAILABLE_OFFLINE - TerminalErrorCode.NO_LAST_SEEN_ACCOUNT -> TerminalExceptionCodeApi.NO_LAST_SEEN_ACCOUNT - TerminalErrorCode.INVALID_OFFLINE_CURRENCY -> TerminalExceptionCodeApi.INVALID_OFFLINE_CURRENCY - TerminalErrorCode.CARD_SWIPE_NOT_AVAILABLE -> TerminalExceptionCodeApi.CARD_SWIPE_NOT_AVAILABLE - TerminalErrorCode.INTERAC_NOT_SUPPORTED_OFFLINE -> - TerminalExceptionCodeApi.INTERAC_NOT_SUPPORTED_OFFLINE - TerminalErrorCode.ONLINE_PIN_NOT_SUPPORTED_OFFLINE -> - TerminalExceptionCodeApi.ONLINE_PIN_NOT_SUPPORTED_OFFLINE - TerminalErrorCode.OFFLINE_AND_CARD_EXPIRED -> TerminalExceptionCodeApi.OFFLINE_AND_CARD_EXPIRED - TerminalErrorCode.OFFLINE_TRANSACTION_DECLINED -> - TerminalExceptionCodeApi.OFFLINE_TRANSACTION_DECLINED - TerminalErrorCode.OFFLINE_COLLECT_AND_CONFIRM_MISMATCH -> - TerminalExceptionCodeApi.OFFLINE_COLLECT_AND_CONFIRM_MISMATCH - TerminalErrorCode.OFFLINE_TESTMODE_PAYMENT_IN_LIVEMODE -> - TerminalExceptionCodeApi.FORWARDING_TEST_MODE_PAYMENT_IN_LIVE_MODE - TerminalErrorCode.OFFLINE_LIVEMODE_PAYMENT_IN_TESTMODE -> - TerminalExceptionCodeApi.FORWARDING_LIVE_MODE_PAYMENT_IN_TEST_MODE - TerminalErrorCode.OFFLINE_PAYMENT_INTENT_NOT_FOUND -> - TerminalExceptionCodeApi.OFFLINE_PAYMENT_INTENT_NOT_FOUND - TerminalErrorCode.MISSING_EMV_DATA -> TerminalExceptionCodeApi.MISSING_EMV_DATA - TerminalErrorCode.CONNECTION_TOKEN_PROVIDER_ERROR_WHILE_FORWARDING -> - TerminalExceptionCodeApi.CONNECTION_TOKEN_PROVIDER_ERROR_WHILE_FORWARDING - TerminalErrorCode.ACCOUNT_ID_MISMATCH_WHILE_FORWARDING -> - TerminalExceptionCodeApi.ACCOUNT_ID_MISMATCH_WHILE_FORWARDING - TerminalErrorCode.FORCE_OFFLINE_WITH_FEATURE_DISABLED -> - TerminalExceptionCodeApi.OFFLINE_BEHAVIOR_FORCE_OFFLINE_WITH_FEATURE_DISABLED - TerminalErrorCode.NOT_CONNECTED_TO_INTERNET_AND_REQUIRE_ONLINE_SET -> - TerminalExceptionCodeApi.NOT_CONNECTED_TO_INTERNET_AND_OFFLINE_BEHAVIOR_REQUIRE_ONLINE - TerminalErrorCode.TEST_CARD_IN_LIVEMODE -> TerminalExceptionCodeApi.TEST_CARD_IN_LIVE_MODE - TerminalErrorCode.COLLECT_INPUTS_APPLICATION_ERROR -> - TerminalExceptionCodeApi.COLLECT_INPUTS_APPLICATION_ERROR - TerminalErrorCode.COLLECT_INPUTS_TIMED_OUT -> TerminalExceptionCodeApi.COLLECT_INPUTS_TIMED_OUT - TerminalErrorCode.COLLECT_INPUTS_INVALID_PARAMETER -> TerminalExceptionCodeApi.INVALID_PARAMETER - TerminalErrorCode.COLLECT_INPUTS_UNSUPPORTED -> - TerminalExceptionCodeApi.COLLECT_INPUTS_UNSUPPORTED - } -} - -fun Reader.toApi(): ReaderApi { - return ReaderApi( - locationStatus = locationStatus.toApi(), - batteryLevel = batteryLevel?.toDouble() ?: -1.0, - deviceType = deviceType.toApi(), - simulated = isSimulated, - availableUpdate = availableUpdate?.hasFirmwareUpdate ?: false, - locationId = location?.id, - location = location?.toApi(), - label = label, - serialNumber = serialNumber!!, - ) -} - -fun LocationStatus.toApi(): LocationStatusApi? { - return when (this) { - LocationStatus.UNKNOWN -> null - LocationStatus.SET -> LocationStatusApi.SET - LocationStatus.NOT_SET -> LocationStatusApi.NOT_SET - } -} - -fun DeviceType.toApi(): DeviceTypeApi? { - return when (this) { - DeviceType.CHIPPER_1X -> DeviceTypeApi.CHIPPER1_X - DeviceType.CHIPPER_2X -> DeviceTypeApi.CHIPPER2_X - DeviceType.STRIPE_M2 -> DeviceTypeApi.STRIPE_M2 - DeviceType.COTS_DEVICE -> DeviceTypeApi.COTS_DEVICE - DeviceType.VERIFONE_P400 -> DeviceTypeApi.VERIFONE_P400 - DeviceType.WISECUBE -> DeviceTypeApi.WISE_CUBE - DeviceType.WISEPAD_3 -> DeviceTypeApi.WISE_PAD3 - DeviceType.WISEPAD_3S -> DeviceTypeApi.WISE_PAD3S - DeviceType.WISEPOS_E -> DeviceTypeApi.WISE_POS_E - DeviceType.WISEPOS_E_DEVKIT -> DeviceTypeApi.WISE_POS_E_DEVKIT - DeviceType.ETNA -> DeviceTypeApi.ETNA - DeviceType.STRIPE_S700 -> DeviceTypeApi.STRIPE_S700 - DeviceType.STRIPE_S700_DEVKIT -> DeviceTypeApi.STRIPE_S700_DEVKIT - DeviceType.UNKNOWN -> null - } -} - -fun ConnectionStatus.toApi(): ConnectionStatusApi { - return when (this) { - ConnectionStatus.NOT_CONNECTED -> ConnectionStatusApi.NOT_CONNECTED - ConnectionStatus.CONNECTING -> ConnectionStatusApi.CONNECTING - ConnectionStatus.CONNECTED -> ConnectionStatusApi.CONNECTED - } -} - -fun ReaderEvent.toApi(): ReaderEventApi { - return when (this) { - ReaderEvent.CARD_INSERTED -> ReaderEventApi.CARD_INSERTED - ReaderEvent.CARD_REMOVED -> ReaderEventApi.CARD_REMOVED - } -} - -fun ReaderDisplayMessage.toApi(): ReaderDisplayMessageApi { - return when (this) { - ReaderDisplayMessage.CHECK_MOBILE_DEVICE -> ReaderDisplayMessageApi.CHECK_MOBILE_DEVICE - ReaderDisplayMessage.RETRY_CARD -> ReaderDisplayMessageApi.RETRY_CARD - ReaderDisplayMessage.INSERT_CARD -> ReaderDisplayMessageApi.INSERT_CARD - ReaderDisplayMessage.INSERT_OR_SWIPE_CARD -> ReaderDisplayMessageApi.INSERT_OR_SWIPE_CARD - ReaderDisplayMessage.SWIPE_CARD -> ReaderDisplayMessageApi.SWIPE_CARD - ReaderDisplayMessage.REMOVE_CARD -> ReaderDisplayMessageApi.REMOVE_CARD - ReaderDisplayMessage.MULTIPLE_CONTACTLESS_CARDS_DETECTED -> - ReaderDisplayMessageApi.MULTIPLE_CONTACTLESS_CARDS_DETECTED - ReaderDisplayMessage.TRY_ANOTHER_READ_METHOD -> ReaderDisplayMessageApi.TRY_ANOTHER_READ_METHOD - ReaderDisplayMessage.TRY_ANOTHER_CARD -> ReaderDisplayMessageApi.TRY_ANOTHER_CARD - ReaderDisplayMessage.CARD_REMOVED_TOO_EARLY -> ReaderDisplayMessageApi.CARD_REMOVED_TOO_EARLY - } -} - -fun ReaderInputOptions.ReaderInputOption.toApi(): ReaderInputOptionApi? { - return when (this) { - ReaderInputOptions.ReaderInputOption.NONE -> null - ReaderInputOptions.ReaderInputOption.INSERT -> ReaderInputOptionApi.INSERT_CARD - ReaderInputOptions.ReaderInputOption.SWIPE -> ReaderInputOptionApi.SWIPE_CARD - ReaderInputOptions.ReaderInputOption.TAP -> ReaderInputOptionApi.TAP_CARD - ReaderInputOptions.ReaderInputOption.MANUAL_ENTRY -> ReaderInputOptionApi.MANUAL_ENTRY - } -} - -fun BatteryStatus.toApi(): BatteryStatusApi? { - return when (this) { - BatteryStatus.UNKNOWN -> null - BatteryStatus.CRITICAL -> BatteryStatusApi.CRITICAL - BatteryStatus.LOW -> BatteryStatusApi.LOW - BatteryStatus.NOMINAL -> BatteryStatusApi.NOMINAL - } -} - -fun ReaderSoftwareUpdate.toApi(): ReaderSoftwareUpdateApi { - return ReaderSoftwareUpdateApi( - components = components.map { it.toApi() }, - keyProfileName = keyProfileName, - onlyInstallRequiredUpdates = onlyInstallRequiredUpdates, - requiredAt = requiredAt.time, - settingsVersion = settingsVersion, - timeEstimate = timeEstimate.toApi(), - version = version, - ) -} - -fun ReaderSoftwareUpdate.UpdateComponent.toApi(): UpdateComponentApi { - return when (this) { - ReaderSoftwareUpdate.UpdateComponent.INCREMENTAL -> UpdateComponentApi.INCREMENTAL - ReaderSoftwareUpdate.UpdateComponent.FIRMWARE -> UpdateComponentApi.FIRMWARE - ReaderSoftwareUpdate.UpdateComponent.CONFIG -> UpdateComponentApi.CONFIG - ReaderSoftwareUpdate.UpdateComponent.KEYS -> UpdateComponentApi.KEYS - } -} - -fun ReaderSoftwareUpdate.UpdateTimeEstimate.toApi(): UpdateTimeEstimateApi { - return when (this) { - ReaderSoftwareUpdate.UpdateTimeEstimate.LESS_THAN_ONE_MINUTE -> - UpdateTimeEstimateApi.LESS_THAN_ONE_MINUTE - ReaderSoftwareUpdate.UpdateTimeEstimate.ONE_TO_TWO_MINUTES -> - UpdateTimeEstimateApi.ONE_TO_TWO_MINUTES - ReaderSoftwareUpdate.UpdateTimeEstimate.TWO_TO_FIVE_MINUTES -> - UpdateTimeEstimateApi.TWO_TO_FIVE_MINUTES - ReaderSoftwareUpdate.UpdateTimeEstimate.FIVE_TO_FIFTEEN_MINUTES -> - UpdateTimeEstimateApi.FIVE_TO_FIFTEEN_MINUTES - } -} - -fun cardBrandToApi(value: String?): CardBrandApi? { - return when (value) { - "amex" -> CardBrandApi.AMEX - "diners" -> CardBrandApi.DINERS_CLUB - "discover" -> CardBrandApi.DISCOVER - "jcb" -> CardBrandApi.JCB - "mastercard" -> CardBrandApi.MASTER_CARD - "unionpay" -> CardBrandApi.UNION_PAY - "visa" -> CardBrandApi.VISA - "unknown" -> null - else -> null - } -} - -fun fundingToApi(value: String?): CardFundingTypeApi? { - return when (value) { - "credit" -> CardFundingTypeApi.CREDIT - "debit" -> CardFundingTypeApi.DEBIT - "prepaid" -> CardFundingTypeApi.PREPAID - "unknown" -> null - else -> null - } -} - -fun CardPresentDetails.toApi(): CardPresentDetailsApi { - return CardPresentDetailsApi( - brand = cardBrandToApi(brand), - country = country, - expMonth = expMonth.toLong(), - expYear = expYear.toLong(), - funding = fundingToApi(funding), - last4 = last4, - cardholderName = cardholderName, - generatedCard = generatedCard, - receipt = receiptDetails?.toApi(), - emvAuthData = emvAuthData, - networks = networks?.toApi(), - incrementalAuthorizationStatus = incrementalAuthorizationStatus.toApi(), - ) -} - -fun ReceiptDetails.toApi(): ReceiptDetailsApi { - return ReceiptDetailsApi( - accountType = accountType, - applicationPreferredName = applicationPreferredName!!, - authorizationCode = authorizationCode, - authorizationResponseCode = authorizationResponseCode!!, - applicationCryptogram = applicationCryptogram!!, - dedicatedFileName = dedicatedFileName!!, - transactionStatusInformation = tsi!!, - terminalVerificationResults = tvr!!, - ) -} - -fun CardNetworks.toApi(): CardNetworksApi { - return CardNetworksApi( - available = - available.map { - cardBrandToApi(it)!! - }, - preferred = preferred, - ) -} - -fun IncrementalAuthorizationStatus.toApi(): IncrementalAuthorizationStatusApi? { - return when (this) { - IncrementalAuthorizationStatus.NOT_SUPPORTED -> IncrementalAuthorizationStatusApi.NOT_SUPPORTED - IncrementalAuthorizationStatus.SUPPORTED -> IncrementalAuthorizationStatusApi.SUPPORTED - IncrementalAuthorizationStatus.UNKNOWN -> null - } -} - -fun PaymentIntent.toApi(): PaymentIntentApi { - return PaymentIntentApi( - id = id!!, - created = created, - status = status!!.toApi(), - amount = amount.toDouble(), - captureMethod = - when (captureMethod!!) { - "automatic" -> CaptureMethodApi.AUTOMATIC - "manual" -> CaptureMethodApi.MANUAL - else -> - throw IllegalArgumentException( - "Not supported CaptureMethod '$captureMethod' on PaymentIntent $id", - ) - }, - currency = currency!!, - metadata = metadata?.toHashMap() ?: hashMapOf(), - charges = getCharges().map { it.toApi() }, - paymentMethod = paymentMethod?.toApi(), - amountDetails = amountDetails?.toApi(), - paymentMethodId = paymentMethodId, - amountTip = amountTip?.toDouble(), - statementDescriptor = statementDescriptor, - statementDescriptorSuffix = statementDescriptorSuffix, - // Only Android - amountCapturable = amountCapturable.toDouble(), - amountReceived = amountReceived.toDouble(), - applicationId = application, - applicationFeeAmount = applicationFeeAmount.toDouble(), - canceledAt = canceledAt, - cancellationReason = cancellationReason, - clientSecret = clientSecret, - confirmationMethod = - when (confirmationMethod) { - "automatic" -> ConfirmationMethodApi.AUTOMATIC - "manual" -> ConfirmationMethodApi.MANUAL - else -> null - }, - description = description, - invoiceId = invoice, - onBehalfOf = onBehalfOf, - receiptEmail = receiptEmail, - reviewId = review, - setupFutureUsage = - when (setupFutureUsage) { - "on_session" -> PaymentIntentUsageApi.ON_SESSION - "off_session" -> PaymentIntentUsageApi.OFF_SESSION - else -> null - }, - transferGroup = transferGroup, - customerId = customer, - ) -} - -fun PaymentIntentStatus.toApi(): PaymentIntentStatusApi { - return when (this) { - PaymentIntentStatus.CANCELED -> PaymentIntentStatusApi.CANCELED - PaymentIntentStatus.PROCESSING -> PaymentIntentStatusApi.PROCESSING - PaymentIntentStatus.REQUIRES_CAPTURE -> PaymentIntentStatusApi.REQUIRES_CAPTURE - PaymentIntentStatus.REQUIRES_CONFIRMATION -> PaymentIntentStatusApi.REQUIRES_CONFIRMATION - PaymentIntentStatus.REQUIRES_PAYMENT_METHOD -> PaymentIntentStatusApi.REQUIRES_PAYMENT_METHOD - PaymentIntentStatus.SUCCEEDED -> PaymentIntentStatusApi.SUCCEEDED - } -} - -fun Location.toApi(): LocationApi { - return LocationApi( - address = address?.toApi(), - displayName = displayName, - id = id, - livemode = livemode, - metadata = metadata?.toHashMap() ?: hashMapOf(), - ) -} - -fun Address.toApi(): AddressApi { - return AddressApi( - city = city, - country = country, - line1 = line1, - line2 = line2, - postalCode = postalCode, - state = state, - ) -} - -fun PaymentStatus.toApi(): PaymentStatusApi { - return when (this) { - PaymentStatus.NOT_READY -> PaymentStatusApi.NOT_READY - PaymentStatus.READY -> PaymentStatusApi.READY - PaymentStatus.WAITING_FOR_INPUT -> PaymentStatusApi.WAITING_FOR_INPUT - PaymentStatus.PROCESSING -> PaymentStatusApi.PROCESSING - } -} - -fun SetupIntent.toApi(): SetupIntentApi { - return SetupIntentApi( - id = id, - created = created, - customerId = customerId, - metadata = metadata.toHashMap(), - usage = usage!!.toApi(), - status = status!!.toApi(), - latestAttempt = latestAttempt?.toApi(), - ) -} - -fun SetupIntentUsage.toApi(): SetupIntentUsageApi { - return when (this) { - SetupIntentUsage.ON_SESSION -> SetupIntentUsageApi.ON_SESSION - SetupIntentUsage.OFF_SESSION -> SetupIntentUsageApi.OFF_SESSION - } -} - -fun SetupIntentStatus.toApi(): SetupIntentStatusApi { - return when (this) { - SetupIntentStatus.REQUIRES_PAYMENT_METHOD -> SetupIntentStatusApi.REQUIRES_PAYMENT_METHOD - SetupIntentStatus.REQUIRES_CONFIRMATION -> SetupIntentStatusApi.REQUIRES_CONFIRMATION - SetupIntentStatus.REQUIRES_ACTION -> SetupIntentStatusApi.REQUIRES_ACTION - SetupIntentStatus.PROCESSING -> SetupIntentStatusApi.PROCESSING - SetupIntentStatus.SUCCEEDED -> SetupIntentStatusApi.SUCCEEDED - SetupIntentStatus.CANCELLED -> SetupIntentStatusApi.CANCELLED - } -} - -fun SetupAttempt.toApi(): SetupAttemptApi { - return SetupAttemptApi( - id = id, - applicationId = applicationId, - created = created, - customerId = customerId, - onBehalfOf = onBehalfOfId, - paymentMethodId = paymentMethodId, - paymentMethodDetails = paymentMethodDetails.toApi(), - setupIntentId = setupIntentId!!, - status = status.toApi(), - ) -} - -fun SetupAttemptStatus.toApi(): SetupAttemptStatusApi { - return when (this) { - SetupAttemptStatus.REQUIRES_CONFIRMATION -> SetupAttemptStatusApi.REQUIRES_CONFIRMATION - SetupAttemptStatus.REQUIRES_ACTION -> SetupAttemptStatusApi.REQUIRES_ACTION - SetupAttemptStatus.PROCESSING -> SetupAttemptStatusApi.PROCESSING - SetupAttemptStatus.SUCCEEDED -> SetupAttemptStatusApi.SUCCEEDED - SetupAttemptStatus.FAILED -> SetupAttemptStatusApi.FAILED - SetupAttemptStatus.ABANDONED -> SetupAttemptStatusApi.ABANDONED - } -} - -fun SetupIntentPaymentMethodDetails.toApi(): SetupAttemptPaymentMethodDetailsApi { - return SetupAttemptPaymentMethodDetailsApi( - cardPresent = cardPresentDetails?.toApi(), - interacPresent = interacPresentDetails?.toApi(), - ) -} - -fun SetupIntentCardPresentDetails.toApi(): SetupAttemptCardPresentDetailsApi { - return SetupAttemptCardPresentDetailsApi( - emvAuthData = emvAuthData!!, - generatedCard = generatedCard!!, - ) -} - -fun Refund.toApi(): RefundApi { - return RefundApi( - id = id, - amount = amount!!, - chargeId = chargeId!!, - created = created!!, - currency = currency!!, - metadata = metadata?.toHashMap() ?: HashMap(), - reason = reason, - status = - when (status) { - "succeeded" -> RefundStatusApi.SUCCEEDED - "pending" -> RefundStatusApi.PENDING - "failed" -> RefundStatusApi.FAILED - else -> null - }, - paymentMethodDetails = paymentMethodDetails?.toApi(), - failureReason = failureReason, - ) -} - -fun PaymentMethodDetails.toApi(): PaymentMethodDetailsApi { - return PaymentMethodDetailsApi( - cardPresent = cardPresentDetails?.toApi(), - interacPresent = interacPresentDetails?.toApi(), - ) -} diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/api/ToHostExtensions.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/api/ToHostExtensions.kt deleted file mode 100644 index 5ac8481..0000000 --- a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/api/ToHostExtensions.kt +++ /dev/null @@ -1,160 +0,0 @@ -package mek.stripeterminal.api - -import com.stripe.stripeterminal.external.models.CaptureMethod -import com.stripe.stripeterminal.external.models.CardPresentCaptureMethod -import com.stripe.stripeterminal.external.models.CardPresentParameters -import com.stripe.stripeterminal.external.models.CardPresentRoutingOptionParameters -import com.stripe.stripeterminal.external.models.Cart -import com.stripe.stripeterminal.external.models.CartLineItem -import com.stripe.stripeterminal.external.models.DeviceType -import com.stripe.stripeterminal.external.models.DiscoveryConfiguration -import com.stripe.stripeterminal.external.models.PaymentIntentParameters -import com.stripe.stripeterminal.external.models.PaymentMethodOptionsParameters -import com.stripe.stripeterminal.external.models.PaymentMethodType -import com.stripe.stripeterminal.external.models.RoutingPriority -import com.stripe.stripeterminal.external.models.TippingConfiguration -import mek.stripeterminal.microsecondsToSeconds - -fun DiscoveryConfigurationApi.toHost(): DiscoveryConfiguration? { - return when (this) { - is BluetoothDiscoveryConfigurationApi -> - DiscoveryConfiguration.BluetoothDiscoveryConfiguration( - isSimulated = isSimulated, - timeout = timeout?.let { microsecondsToSeconds(it) } ?: 0, - ) - is BluetoothProximityDiscoveryConfigurationApi -> null - is HandoffDiscoveryConfigurationApi -> DiscoveryConfiguration.HandoffDiscoveryConfiguration() - is InternetDiscoveryConfigurationApi -> - DiscoveryConfiguration.InternetDiscoveryConfiguration( - isSimulated = isSimulated, - location = locationId, - ) - is LocalMobileDiscoveryConfigurationApi -> - DiscoveryConfiguration.LocalMobileDiscoveryConfiguration( - isSimulated = isSimulated, - ) - is UsbDiscoveryConfigurationApi -> - DiscoveryConfiguration.UsbDiscoveryConfiguration( - isSimulated = isSimulated, - timeout = timeout?.let { microsecondsToSeconds(it) } ?: 0, - ) - } -} - -fun DeviceTypeApi.toHost(): DeviceType? { - return when (this) { - DeviceTypeApi.CHIPPER1_X -> DeviceType.CHIPPER_1X - DeviceTypeApi.CHIPPER2_X -> DeviceType.CHIPPER_2X - DeviceTypeApi.STRIPE_M2 -> DeviceType.STRIPE_M2 - DeviceTypeApi.COTS_DEVICE -> DeviceType.COTS_DEVICE - DeviceTypeApi.VERIFONE_P400 -> DeviceType.VERIFONE_P400 - DeviceTypeApi.WISE_CUBE -> DeviceType.WISECUBE - DeviceTypeApi.WISE_PAD3 -> DeviceType.WISEPAD_3 - DeviceTypeApi.WISE_PAD3S -> DeviceType.WISEPAD_3S - DeviceTypeApi.WISE_POS_E -> DeviceType.WISEPOS_E - DeviceTypeApi.WISE_POS_E_DEVKIT -> DeviceType.WISEPOS_E_DEVKIT - DeviceTypeApi.ETNA -> DeviceType.ETNA - DeviceTypeApi.STRIPE_S700 -> DeviceType.STRIPE_S700 - DeviceTypeApi.STRIPE_S700_DEVKIT -> DeviceType.STRIPE_S700_DEVKIT - DeviceTypeApi.APPLE_BUILT_IN -> null - } -} - -fun CartApi.toHost(): Cart { - return Cart.Builder( - currency = currency, - tax = tax, - total = total, - lineItems = lineItems.map { it.toHost() }, - ) - .build() -} - -fun CartLineItemApi.toHost(): CartLineItem { - return CartLineItem.Builder( - description = description, - quantity = quantity.toInt(), - amount = amount, - ) - .build() -} - -fun PaymentIntentUsageApi.toHost(): String { - return when (this) { - PaymentIntentUsageApi.OFF_SESSION -> "off_session" - PaymentIntentUsageApi.ON_SESSION -> "on_session" - } -} - -fun PaymentIntentParametersApi.toHost(): PaymentIntentParameters { - val b = - PaymentIntentParameters.Builder( - amount = amount, - currency = currency, - captureMethod = - when (captureMethod) { - CaptureMethodApi.MANUAL -> CaptureMethod.Manual - CaptureMethodApi.AUTOMATIC -> CaptureMethod.Automatic - }, - allowedPaymentMethodTypes = - paymentMethodTypes.map { - when (it) { - PaymentMethodTypeApi.CARD_PRESENT -> PaymentMethodType.CARD_PRESENT - PaymentMethodTypeApi.CARD -> PaymentMethodType.CARD - PaymentMethodTypeApi.INTERACT_PRESENT -> PaymentMethodType.INTERAC_PRESENT - } - }, - ) - b.setMetadata(metadata) - description?.let(b::setDescription) - statementDescriptor?.let(b::setStatementDescriptor) - statementDescriptorSuffix?.let(b::setStatementDescriptorSuffix) - receiptEmail?.let(b::setReceiptEmail) - customerId?.let(b::setCustomer) - applicationFeeAmount?.let(b::setApplicationFeeAmount) - transferDataDestination?.let(b::setTransferDataDestination) - transferGroup?.let(b::setTransferGroup) - onBehalfOf?.let(b::setOnBehalfOf) - setupFutureUsage?.toHost()?.let(b::setSetupFutureUsage) - paymentMethodOptionsParameters?.let { b.setPaymentMethodOptionsParameters(it.toHost()) } - return b.build() -} - -fun PaymentMethodOptionsParametersApi.toHost(): PaymentMethodOptionsParameters { - return PaymentMethodOptionsParameters.Builder() - .setCardPresentParameters(cardPresentParameters.toHost()) - .build() -} - -fun TippingConfigurationApi.toHost(): TippingConfiguration { - return TippingConfiguration.Builder().setEligibleAmount(eligibleAmount).build() -} - -fun CardPresentParametersApi.toHost(): CardPresentParameters { - val b = CardPresentParameters.Builder() - captureMethod?.let { b.setCaptureMethod(it.toHost()) } - requestExtendedAuthorization?.let { b.setRequestExtendedAuthorization(it) } - requestIncrementalAuthorizationSupport?.let { b.setRequestIncrementalAuthorizationSupport(it) } - requestedPriority?.let { b.setRouting(CardPresentRoutingOptionParameters(it.toHost())) } - return b.build() -} - -fun CardPresentCaptureMethodApi.toHost(): CardPresentCaptureMethod { - return when (this) { - CardPresentCaptureMethodApi.MANUAL_PREFERRED -> CardPresentCaptureMethod.ManualPreferred - } -} - -fun CardPresentRoutingApi.toHost(): RoutingPriority { - return when (this) { - CardPresentRoutingApi.DOMESTIC -> RoutingPriority.DOMESTIC - CardPresentRoutingApi.INTERNATIONAL -> RoutingPriority.INTERNATIONAL - } -} - -fun SetupIntentUsageApi.toHost(): String { - return when (this) { - SetupIntentUsageApi.ON_SESSION -> "on_session" - SetupIntentUsageApi.OFF_SESSION -> "off_session" - } -} diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/CardMappings.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/CardMappings.kt index 662d123..54ba9d6 100644 --- a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/CardMappings.kt +++ b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/CardMappings.kt @@ -1,9 +1,24 @@ package mek.stripeterminal.mappings import com.stripe.stripeterminal.external.models.CardDetails +import com.stripe.stripeterminal.external.models.CardNetworks +import com.stripe.stripeterminal.external.models.CardPresentCaptureMethod +import com.stripe.stripeterminal.external.models.CardPresentDetails +import com.stripe.stripeterminal.external.models.CardPresentParameters +import com.stripe.stripeterminal.external.models.CardPresentRoutingOptionParameters +import com.stripe.stripeterminal.external.models.IncrementalAuthorizationStatus +import com.stripe.stripeterminal.external.models.ReceiptDetails +import com.stripe.stripeterminal.external.models.RoutingPriority +import mek.stripeterminal.api.CardBrandApi import mek.stripeterminal.api.CardDetailsApi -import mek.stripeterminal.api.cardBrandToApi -import mek.stripeterminal.api.fundingToApi +import mek.stripeterminal.api.CardFundingTypeApi +import mek.stripeterminal.api.CardNetworksApi +import mek.stripeterminal.api.CardPresentCaptureMethodApi +import mek.stripeterminal.api.CardPresentDetailsApi +import mek.stripeterminal.api.CardPresentParametersApi +import mek.stripeterminal.api.CardPresentRoutingApi +import mek.stripeterminal.api.IncrementalAuthorizationStatusApi +import mek.stripeterminal.api.ReceiptDetailsApi fun CardDetails.toApi(): CardDetailsApi { return CardDetailsApi( @@ -15,3 +30,99 @@ fun CardDetails.toApi(): CardDetailsApi { last4 = last4, ) } + +fun cardBrandToApi(value: String?): CardBrandApi? { + return when (value) { + "amex" -> CardBrandApi.AMEX + "diners" -> CardBrandApi.DINERS_CLUB + "discover" -> CardBrandApi.DISCOVER + "jcb" -> CardBrandApi.JCB + "mastercard" -> CardBrandApi.MASTER_CARD + "unionpay" -> CardBrandApi.UNION_PAY + "visa" -> CardBrandApi.VISA + "unknown" -> null + else -> null + } +} + +fun fundingToApi(value: String?): CardFundingTypeApi? { + return when (value) { + "credit" -> CardFundingTypeApi.CREDIT + "debit" -> CardFundingTypeApi.DEBIT + "prepaid" -> CardFundingTypeApi.PREPAID + "unknown" -> null + else -> null + } +} + +fun CardPresentDetails.toApi(): CardPresentDetailsApi { + return CardPresentDetailsApi( + brand = cardBrandToApi(brand), + country = country, + expMonth = expMonth.toLong(), + expYear = expYear.toLong(), + funding = fundingToApi(funding), + last4 = last4, + cardholderName = cardholderName, + generatedCard = generatedCard, + receipt = receiptDetails?.toApi(), + emvAuthData = emvAuthData, + networks = networks?.toApi(), + incrementalAuthorizationStatus = incrementalAuthorizationStatus.toApi(), + ) +} + +fun ReceiptDetails.toApi(): ReceiptDetailsApi { + return ReceiptDetailsApi( + accountType = accountType, + applicationPreferredName = applicationPreferredName!!, + authorizationCode = authorizationCode, + authorizationResponseCode = authorizationResponseCode!!, + applicationCryptogram = applicationCryptogram!!, + dedicatedFileName = dedicatedFileName!!, + transactionStatusInformation = tsi!!, + terminalVerificationResults = tvr!!, + ) +} + +fun CardNetworks.toApi(): CardNetworksApi { + return CardNetworksApi( + available = + available.map { + cardBrandToApi(it)!! + }, + preferred = preferred, + ) +} + +fun IncrementalAuthorizationStatus.toApi(): IncrementalAuthorizationStatusApi? { + return when (this) { + IncrementalAuthorizationStatus.NOT_SUPPORTED -> IncrementalAuthorizationStatusApi.NOT_SUPPORTED + IncrementalAuthorizationStatus.SUPPORTED -> IncrementalAuthorizationStatusApi.SUPPORTED + IncrementalAuthorizationStatus.UNKNOWN -> null + } +} + +// PARAMS + +fun CardPresentParametersApi.toHost(): CardPresentParameters { + val b = CardPresentParameters.Builder() + captureMethod?.let { b.setCaptureMethod(it.toHost()) } + requestExtendedAuthorization?.let { b.setRequestExtendedAuthorization(it) } + requestIncrementalAuthorizationSupport?.let { b.setRequestIncrementalAuthorizationSupport(it) } + requestedPriority?.let { b.setRouting(CardPresentRoutingOptionParameters(it.toHost())) } + return b.build() +} + +fun CardPresentCaptureMethodApi.toHost(): CardPresentCaptureMethod { + return when (this) { + CardPresentCaptureMethodApi.MANUAL_PREFERRED -> CardPresentCaptureMethod.ManualPreferred + } +} + +fun CardPresentRoutingApi.toHost(): RoutingPriority { + return when (this) { + CardPresentRoutingApi.DOMESTIC -> RoutingPriority.DOMESTIC + CardPresentRoutingApi.INTERNATIONAL -> RoutingPriority.INTERNATIONAL + } +} diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/ChargeMappings.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/ChargeMappings.kt index 4c672d0..8289312 100644 --- a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/ChargeMappings.kt +++ b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/ChargeMappings.kt @@ -1,8 +1,10 @@ package mek.stripeterminal.mappings import com.stripe.stripeterminal.external.models.Charge +import com.stripe.stripeterminal.external.models.PaymentMethodDetails import mek.stripeterminal.api.ChargeApi import mek.stripeterminal.api.ChargeStatusApi +import mek.stripeterminal.api.PaymentMethodDetailsApi import mek.stripeterminal.api.toApi import mek.stripeterminal.toHashMap @@ -26,3 +28,10 @@ fun Charge.toApi(): ChargeApi { authorizationCode = authorizationCode, ) } + +fun PaymentMethodDetails.toApi(): PaymentMethodDetailsApi { + return PaymentMethodDetailsApi( + cardPresent = cardPresentDetails?.toApi(), + interacPresent = interacPresentDetails?.toApi(), + ) +} diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/ExceptionMappings.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/ExceptionMappings.kt new file mode 100644 index 0000000..d13bbc7 --- /dev/null +++ b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/ExceptionMappings.kt @@ -0,0 +1,155 @@ +package mek.stripeterminal.mappings + +import com.stripe.stripeterminal.external.models.TerminalException +import mek.stripeterminal.api.PlatformError +import mek.stripeterminal.api.TerminalExceptionApi +import mek.stripeterminal.api.TerminalExceptionCodeApi + +fun TerminalException.toPlatformError(): PlatformError { + return toApi().toPlatformError() +} + +fun TerminalExceptionApi.toPlatformError(): PlatformError { + return PlatformError(code = "mek_stripe_terminal", message = null, details = serialize()) +} + +fun TerminalException.toApi(): TerminalExceptionApi { + val code = errorCode.toApiCode() + return TerminalExceptionApi( + code = code ?: TerminalExceptionCodeApi.UNKNOWN, + message = errorMessage, + stackTrace = stackTraceToString(), + paymentIntent = paymentIntent?.toApi(), + apiError = apiError?.toString(), + ) +} + +private fun TerminalException.TerminalErrorCode.toApiCode(): TerminalExceptionCodeApi? { + return when (this) { + TerminalException.TerminalErrorCode.CANCEL_FAILED -> TerminalExceptionCodeApi.CANCEL_FAILED + TerminalException.TerminalErrorCode.NOT_CONNECTED_TO_READER -> TerminalExceptionCodeApi.NOT_CONNECTED_TO_READER + TerminalException.TerminalErrorCode.ALREADY_CONNECTED_TO_READER -> + TerminalExceptionCodeApi.ALREADY_CONNECTED_TO_READER + TerminalException.TerminalErrorCode.BLUETOOTH_PERMISSION_DENIED -> + TerminalExceptionCodeApi.BLUETOOTH_PERMISSION_DENIED + TerminalException.TerminalErrorCode.CONFIRM_INVALID_PAYMENT_INTENT -> + TerminalExceptionCodeApi.CONFIRM_INVALID_PAYMENT_INTENT + TerminalException.TerminalErrorCode.INVALID_CLIENT_SECRET -> TerminalExceptionCodeApi.INVALID_CLIENT_SECRET + TerminalException.TerminalErrorCode.UNSUPPORTED_OPERATION -> TerminalExceptionCodeApi.UNSUPPORTED_OPERATION + TerminalException.TerminalErrorCode.UNEXPECTED_OPERATION -> TerminalExceptionCodeApi.UNEXPECTED_OPERATION + TerminalException.TerminalErrorCode.UNSUPPORTED_SDK -> TerminalExceptionCodeApi.UNSUPPORTED_SDK + TerminalException.TerminalErrorCode.USB_PERMISSION_DENIED -> TerminalExceptionCodeApi.USB_PERMISSION_DENIED + TerminalException.TerminalErrorCode.MISSING_PREREQUISITE -> null + TerminalException.TerminalErrorCode.MISSING_REQUIRED_PARAMETER -> TerminalExceptionCodeApi.INVALID_PARAMETER + TerminalException.TerminalErrorCode.INVALID_REQUIRED_PARAMETER -> + TerminalExceptionCodeApi.INVALID_REQUIRED_PARAMETER + TerminalException.TerminalErrorCode.INVALID_TIP_PARAMETER -> TerminalExceptionCodeApi.INVALID_TIP_PARAMETER + TerminalException.TerminalErrorCode.LOCAL_MOBILE_LIBRARY_NOT_INCLUDED -> null + TerminalException.TerminalErrorCode.LOCAL_MOBILE_UNSUPPORTED_DEVICE -> + TerminalExceptionCodeApi.LOCAL_MOBILE_UNSUPPORTED_DEVICE + TerminalException.TerminalErrorCode.LOCAL_MOBILE_UNSUPPORTED_ANDROID_VERSION -> + TerminalExceptionCodeApi.LOCAL_MOBILE_UNSUPPORTED_OPERATING_SYSTEM_VERSION + TerminalException.TerminalErrorCode.LOCAL_MOBILE_DEVICE_TAMPERED -> + TerminalExceptionCodeApi.LOCAL_MOBILE_DEVICE_TAMPERED + TerminalException.TerminalErrorCode.LOCAL_MOBILE_DEBUG_NOT_SUPPORTED -> + TerminalExceptionCodeApi.LOCAL_MOBILE_DEBUG_NOT_SUPPORTED + TerminalException.TerminalErrorCode.OFFLINE_MODE_UNSUPPORTED_ANDROID_VERSION -> + TerminalExceptionCodeApi.OFFLINE_MODE_UNSUPPORTED_OPERATING_SYSTEM_VERSION + TerminalException.TerminalErrorCode.CANCELED -> TerminalExceptionCodeApi.CANCELED + TerminalException.TerminalErrorCode.LOCATION_SERVICES_DISABLED -> + TerminalExceptionCodeApi.LOCATION_SERVICES_DISABLED + TerminalException.TerminalErrorCode.BLUETOOTH_SCAN_TIMED_OUT -> TerminalExceptionCodeApi.BLUETOOTH_SCAN_TIMED_OUT + TerminalException.TerminalErrorCode.BLUETOOTH_LOW_ENERGY_UNSUPPORTED -> + TerminalExceptionCodeApi.BLUETOOTH_LOW_ENERGY_UNSUPPORTED + TerminalException.TerminalErrorCode.READER_SOFTWARE_UPDATE_FAILED_BATTERY_LOW -> + TerminalExceptionCodeApi.READER_SOFTWARE_UPDATE_FAILED_BATTERY_LOW + TerminalException.TerminalErrorCode.READER_SOFTWARE_UPDATE_FAILED_INTERRUPTED -> + TerminalExceptionCodeApi.READER_SOFTWARE_UPDATE_FAILED_INTERRUPTED + TerminalException.TerminalErrorCode.CARD_INSERT_NOT_READ -> TerminalExceptionCodeApi.CARD_INSERT_NOT_READ + TerminalException.TerminalErrorCode.CARD_SWIPE_NOT_READ -> TerminalExceptionCodeApi.CARD_SWIPE_NOT_READ + TerminalException.TerminalErrorCode.CARD_READ_TIMED_OUT -> TerminalExceptionCodeApi.CARD_READ_TIMED_OUT + TerminalException.TerminalErrorCode.CARD_REMOVED -> TerminalExceptionCodeApi.CARD_REMOVED + TerminalException.TerminalErrorCode.CUSTOMER_CONSENT_REQUIRED -> + TerminalExceptionCodeApi.CUSTOMER_CONSENT_REQUIRED + TerminalException.TerminalErrorCode.CARD_LEFT_IN_READER -> TerminalExceptionCodeApi.CARD_LEFT_IN_READER + TerminalException.TerminalErrorCode.USB_DISCOVERY_TIMED_OUT -> TerminalExceptionCodeApi.USB_DISCOVERY_TIMED_OUT + TerminalException.TerminalErrorCode.FEATURE_NOT_ENABLED_ON_ACCOUNT -> + TerminalExceptionCodeApi.FEATURE_NOT_ENABLED_ON_ACCOUNT + TerminalException.TerminalErrorCode.READER_BUSY -> TerminalExceptionCodeApi.READER_BUSY + TerminalException.TerminalErrorCode.READER_COMMUNICATION_ERROR -> + TerminalExceptionCodeApi.READER_COMMUNICATION_ERROR + TerminalException.TerminalErrorCode.BLUETOOTH_ERROR -> TerminalExceptionCodeApi.BLUETOOTH_ERROR + TerminalException.TerminalErrorCode.BLUETOOTH_DISCONNECTED -> TerminalExceptionCodeApi.BLUETOOTH_DISCONNECTED + TerminalException.TerminalErrorCode.BLUETOOTH_RECONNECT_STARTED -> + TerminalExceptionCodeApi.BLUETOOTH_RECONNECT_STARTED + TerminalException.TerminalErrorCode.USB_DISCONNECTED -> TerminalExceptionCodeApi.USB_DISCONNECTED + TerminalException.TerminalErrorCode.USB_RECONNECT_STARTED -> TerminalExceptionCodeApi.USB_RECONNECT_STARTED + TerminalException.TerminalErrorCode.READER_CONNECTED_TO_ANOTHER_DEVICE -> + TerminalExceptionCodeApi.READER_CONNECTED_TO_ANOTHER_DEVICE + TerminalException.TerminalErrorCode.READER_SOFTWARE_UPDATE_FAILED -> + TerminalExceptionCodeApi.READER_SOFTWARE_UPDATE_FAILED + TerminalException.TerminalErrorCode.READER_SOFTWARE_UPDATE_FAILED_READER_ERROR -> + TerminalExceptionCodeApi.READER_SOFTWARE_UPDATE_FAILED_READER_ERROR + TerminalException.TerminalErrorCode.READER_SOFTWARE_UPDATE_FAILED_SERVER_ERROR -> + TerminalExceptionCodeApi.READER_SOFTWARE_UPDATE_FAILED_SERVER_ERROR + TerminalException.TerminalErrorCode.LOCAL_MOBILE_NFC_DISABLED -> TerminalExceptionCodeApi.NFC_DISABLED + TerminalException.TerminalErrorCode.UNSUPPORTED_READER_VERSION -> + TerminalExceptionCodeApi.UNSUPPORTED_READER_VERSION + TerminalException.TerminalErrorCode.UNEXPECTED_SDK_ERROR -> TerminalExceptionCodeApi.UNEXPECTED_SDK_ERROR + TerminalException.TerminalErrorCode.DECLINED_BY_STRIPE_API -> TerminalExceptionCodeApi.DECLINED_BY_STRIPE_API + TerminalException.TerminalErrorCode.DECLINED_BY_READER -> TerminalExceptionCodeApi.DECLINED_BY_READER + TerminalException.TerminalErrorCode.REQUEST_TIMED_OUT -> TerminalExceptionCodeApi.REQUEST_TIMED_OUT + TerminalException.TerminalErrorCode.STRIPE_API_CONNECTION_ERROR -> + TerminalExceptionCodeApi.STRIPE_API_CONNECTION_ERROR + TerminalException.TerminalErrorCode.STRIPE_API_ERROR -> TerminalExceptionCodeApi.STRIPE_API_ERROR + TerminalException.TerminalErrorCode.STRIPE_API_RESPONSE_DECODING_ERROR -> + TerminalExceptionCodeApi.STRIPE_API_RESPONSE_DECODING_ERROR + TerminalException.TerminalErrorCode.CONNECTION_TOKEN_PROVIDER_ERROR -> + TerminalExceptionCodeApi.CONNECTION_TOKEN_PROVIDER_ERROR + TerminalException.TerminalErrorCode.SESSION_EXPIRED -> TerminalExceptionCodeApi.SESSION_EXPIRED + TerminalException.TerminalErrorCode.ANDROID_API_LEVEL_ERROR -> + TerminalExceptionCodeApi.UNSUPPORTED_MOBILE_DEVICE_CONFIGURATION + TerminalException.TerminalErrorCode.AMOUNT_EXCEEDS_MAX_OFFLINE_AMOUNT -> + TerminalExceptionCodeApi.AMOUNT_EXCEEDS_MAX_OFFLINE_AMOUNT + TerminalException.TerminalErrorCode.OFFLINE_PAYMENTS_DATABASE_TOO_LARGE -> + TerminalExceptionCodeApi.OFFLINE_PAYMENTS_DATABASE_TOO_LARGE + TerminalException.TerminalErrorCode.READER_CONNECTION_NOT_AVAILABLE_OFFLINE -> + TerminalExceptionCodeApi.READER_CONNECTION_NOT_AVAILABLE_OFFLINE + TerminalException.TerminalErrorCode.LOCATION_CONNECTION_NOT_AVAILABLE_OFFLINE -> + TerminalExceptionCodeApi.LOCATION_CONNECTION_NOT_AVAILABLE_OFFLINE + TerminalException.TerminalErrorCode.NO_LAST_SEEN_ACCOUNT -> TerminalExceptionCodeApi.NO_LAST_SEEN_ACCOUNT + TerminalException.TerminalErrorCode.INVALID_OFFLINE_CURRENCY -> TerminalExceptionCodeApi.INVALID_OFFLINE_CURRENCY + TerminalException.TerminalErrorCode.CARD_SWIPE_NOT_AVAILABLE -> TerminalExceptionCodeApi.CARD_SWIPE_NOT_AVAILABLE + TerminalException.TerminalErrorCode.INTERAC_NOT_SUPPORTED_OFFLINE -> + TerminalExceptionCodeApi.INTERAC_NOT_SUPPORTED_OFFLINE + TerminalException.TerminalErrorCode.ONLINE_PIN_NOT_SUPPORTED_OFFLINE -> + TerminalExceptionCodeApi.ONLINE_PIN_NOT_SUPPORTED_OFFLINE + TerminalException.TerminalErrorCode.OFFLINE_AND_CARD_EXPIRED -> TerminalExceptionCodeApi.OFFLINE_AND_CARD_EXPIRED + TerminalException.TerminalErrorCode.OFFLINE_TRANSACTION_DECLINED -> + TerminalExceptionCodeApi.OFFLINE_TRANSACTION_DECLINED + TerminalException.TerminalErrorCode.OFFLINE_COLLECT_AND_CONFIRM_MISMATCH -> + TerminalExceptionCodeApi.OFFLINE_COLLECT_AND_CONFIRM_MISMATCH + TerminalException.TerminalErrorCode.OFFLINE_TESTMODE_PAYMENT_IN_LIVEMODE -> + TerminalExceptionCodeApi.FORWARDING_TEST_MODE_PAYMENT_IN_LIVE_MODE + TerminalException.TerminalErrorCode.OFFLINE_LIVEMODE_PAYMENT_IN_TESTMODE -> + TerminalExceptionCodeApi.FORWARDING_LIVE_MODE_PAYMENT_IN_TEST_MODE + TerminalException.TerminalErrorCode.OFFLINE_PAYMENT_INTENT_NOT_FOUND -> + TerminalExceptionCodeApi.OFFLINE_PAYMENT_INTENT_NOT_FOUND + TerminalException.TerminalErrorCode.MISSING_EMV_DATA -> TerminalExceptionCodeApi.MISSING_EMV_DATA + TerminalException.TerminalErrorCode.CONNECTION_TOKEN_PROVIDER_ERROR_WHILE_FORWARDING -> + TerminalExceptionCodeApi.CONNECTION_TOKEN_PROVIDER_ERROR_WHILE_FORWARDING + TerminalException.TerminalErrorCode.ACCOUNT_ID_MISMATCH_WHILE_FORWARDING -> + TerminalExceptionCodeApi.ACCOUNT_ID_MISMATCH_WHILE_FORWARDING + TerminalException.TerminalErrorCode.FORCE_OFFLINE_WITH_FEATURE_DISABLED -> + TerminalExceptionCodeApi.OFFLINE_BEHAVIOR_FORCE_OFFLINE_WITH_FEATURE_DISABLED + TerminalException.TerminalErrorCode.NOT_CONNECTED_TO_INTERNET_AND_REQUIRE_ONLINE_SET -> + TerminalExceptionCodeApi.NOT_CONNECTED_TO_INTERNET_AND_OFFLINE_BEHAVIOR_REQUIRE_ONLINE + TerminalException.TerminalErrorCode.TEST_CARD_IN_LIVEMODE -> TerminalExceptionCodeApi.TEST_CARD_IN_LIVE_MODE + TerminalException.TerminalErrorCode.COLLECT_INPUTS_APPLICATION_ERROR -> + TerminalExceptionCodeApi.COLLECT_INPUTS_APPLICATION_ERROR + TerminalException.TerminalErrorCode.COLLECT_INPUTS_TIMED_OUT -> TerminalExceptionCodeApi.COLLECT_INPUTS_TIMED_OUT + TerminalException.TerminalErrorCode.COLLECT_INPUTS_INVALID_PARAMETER -> TerminalExceptionCodeApi.INVALID_PARAMETER + TerminalException.TerminalErrorCode.COLLECT_INPUTS_UNSUPPORTED -> + TerminalExceptionCodeApi.COLLECT_INPUTS_UNSUPPORTED + } +} diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/PaymentIntentMappings.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/PaymentIntentMappings.kt index eb17641..8656b59 100644 --- a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/PaymentIntentMappings.kt +++ b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/PaymentIntentMappings.kt @@ -1,10 +1,153 @@ package mek.stripeterminal.mappings import com.stripe.stripeterminal.external.models.AmountDetails +import com.stripe.stripeterminal.external.models.CaptureMethod +import com.stripe.stripeterminal.external.models.PaymentIntent +import com.stripe.stripeterminal.external.models.PaymentIntentParameters +import com.stripe.stripeterminal.external.models.PaymentIntentStatus +import com.stripe.stripeterminal.external.models.PaymentMethodOptionsParameters +import com.stripe.stripeterminal.external.models.PaymentMethodType +import com.stripe.stripeterminal.external.models.PaymentStatus import mek.stripeterminal.api.AmountDetailsApi +import mek.stripeterminal.api.CaptureMethodApi +import mek.stripeterminal.api.ConfirmationMethodApi +import mek.stripeterminal.api.PaymentIntentApi +import mek.stripeterminal.api.PaymentIntentParametersApi +import mek.stripeterminal.api.PaymentIntentStatusApi +import mek.stripeterminal.api.PaymentIntentUsageApi +import mek.stripeterminal.api.PaymentMethodOptionsParametersApi +import mek.stripeterminal.api.PaymentMethodTypeApi +import mek.stripeterminal.api.PaymentStatusApi +import mek.stripeterminal.api.toHost +import mek.stripeterminal.toHashMap + +fun PaymentIntent.toApi(): PaymentIntentApi { + return PaymentIntentApi( + id = id!!, + created = created, + status = status!!.toApi(), + amount = amount.toDouble(), + captureMethod = + when (captureMethod!!) { + "automatic" -> CaptureMethodApi.AUTOMATIC + "manual" -> CaptureMethodApi.MANUAL + else -> + throw IllegalArgumentException( + "Not supported CaptureMethod '$captureMethod' on PaymentIntent $id", + ) + }, + currency = currency!!, + metadata = metadata?.toHashMap() ?: hashMapOf(), + charges = getCharges().map { it.toApi() }, + paymentMethod = paymentMethod?.toApi(), + amountDetails = amountDetails?.toApi(), + paymentMethodId = paymentMethodId, + amountTip = amountTip?.toDouble(), + statementDescriptor = statementDescriptor, + statementDescriptorSuffix = statementDescriptorSuffix, + // Only Android + amountCapturable = amountCapturable.toDouble(), + amountReceived = amountReceived.toDouble(), + applicationId = application, + applicationFeeAmount = applicationFeeAmount.toDouble(), + canceledAt = canceledAt, + cancellationReason = cancellationReason, + clientSecret = clientSecret, + confirmationMethod = + when (confirmationMethod) { + "automatic" -> ConfirmationMethodApi.AUTOMATIC + "manual" -> ConfirmationMethodApi.MANUAL + else -> null + }, + description = description, + invoiceId = invoice, + onBehalfOf = onBehalfOf, + receiptEmail = receiptEmail, + reviewId = review, + setupFutureUsage = + when (setupFutureUsage) { + "on_session" -> PaymentIntentUsageApi.ON_SESSION + "off_session" -> PaymentIntentUsageApi.OFF_SESSION + else -> null + }, + transferGroup = transferGroup, + customerId = customer, + ) +} + +fun PaymentIntentStatus.toApi(): PaymentIntentStatusApi { + return when (this) { + PaymentIntentStatus.CANCELED -> PaymentIntentStatusApi.CANCELED + PaymentIntentStatus.PROCESSING -> PaymentIntentStatusApi.PROCESSING + PaymentIntentStatus.REQUIRES_CAPTURE -> PaymentIntentStatusApi.REQUIRES_CAPTURE + PaymentIntentStatus.REQUIRES_CONFIRMATION -> PaymentIntentStatusApi.REQUIRES_CONFIRMATION + PaymentIntentStatus.REQUIRES_PAYMENT_METHOD -> PaymentIntentStatusApi.REQUIRES_PAYMENT_METHOD + PaymentIntentStatus.SUCCEEDED -> PaymentIntentStatusApi.SUCCEEDED + } +} fun AmountDetails.toApi(): AmountDetailsApi { return AmountDetailsApi( tip = tip?.toApi(), ) } + +// PARAMS + +fun PaymentIntentUsageApi.toHost(): String { + return when (this) { + PaymentIntentUsageApi.OFF_SESSION -> "off_session" + PaymentIntentUsageApi.ON_SESSION -> "on_session" + } +} + +fun PaymentIntentParametersApi.toHost(): PaymentIntentParameters { + val b = + PaymentIntentParameters.Builder( + amount = amount, + currency = currency, + captureMethod = + when (captureMethod) { + CaptureMethodApi.MANUAL -> CaptureMethod.Manual + CaptureMethodApi.AUTOMATIC -> CaptureMethod.Automatic + }, + allowedPaymentMethodTypes = + paymentMethodTypes.map { + when (it) { + PaymentMethodTypeApi.CARD_PRESENT -> PaymentMethodType.CARD_PRESENT + PaymentMethodTypeApi.CARD -> PaymentMethodType.CARD + PaymentMethodTypeApi.INTERACT_PRESENT -> PaymentMethodType.INTERAC_PRESENT + } + }, + ) + b.setMetadata(metadata) + description?.let(b::setDescription) + statementDescriptor?.let(b::setStatementDescriptor) + statementDescriptorSuffix?.let(b::setStatementDescriptorSuffix) + receiptEmail?.let(b::setReceiptEmail) + customerId?.let(b::setCustomer) + applicationFeeAmount?.let(b::setApplicationFeeAmount) + transferDataDestination?.let(b::setTransferDataDestination) + transferGroup?.let(b::setTransferGroup) + onBehalfOf?.let(b::setOnBehalfOf) + setupFutureUsage?.toHost()?.let(b::setSetupFutureUsage) + paymentMethodOptionsParameters?.let { b.setPaymentMethodOptionsParameters(it.toHost()) } + return b.build() +} + +fun PaymentMethodOptionsParametersApi.toHost(): PaymentMethodOptionsParameters { + return PaymentMethodOptionsParameters.Builder() + .setCardPresentParameters(cardPresentParameters.toHost()) + .build() +} + +// EXTRA + +fun PaymentStatus.toApi(): PaymentStatusApi { + return when (this) { + PaymentStatus.NOT_READY -> PaymentStatusApi.NOT_READY + PaymentStatus.READY -> PaymentStatusApi.READY + PaymentStatus.WAITING_FOR_INPUT -> PaymentStatusApi.WAITING_FOR_INPUT + PaymentStatus.PROCESSING -> PaymentStatusApi.PROCESSING + } +} diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/ReaderMappings.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/ReaderMappings.kt new file mode 100644 index 0000000..a3a7489 --- /dev/null +++ b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/ReaderMappings.kt @@ -0,0 +1,254 @@ +package mek.stripeterminal.mappings + +import com.stripe.stripeterminal.external.models.Address +import com.stripe.stripeterminal.external.models.BatteryStatus +import com.stripe.stripeterminal.external.models.Cart +import com.stripe.stripeterminal.external.models.CartLineItem +import com.stripe.stripeterminal.external.models.ConnectionStatus +import com.stripe.stripeterminal.external.models.DeviceType +import com.stripe.stripeterminal.external.models.DiscoveryConfiguration +import com.stripe.stripeterminal.external.models.Location +import com.stripe.stripeterminal.external.models.LocationStatus +import com.stripe.stripeterminal.external.models.Reader +import com.stripe.stripeterminal.external.models.ReaderDisplayMessage +import com.stripe.stripeterminal.external.models.ReaderEvent +import com.stripe.stripeterminal.external.models.ReaderInputOptions +import com.stripe.stripeterminal.external.models.ReaderSoftwareUpdate +import mek.stripeterminal.api.AddressApi +import mek.stripeterminal.api.BatteryStatusApi +import mek.stripeterminal.api.BluetoothDiscoveryConfigurationApi +import mek.stripeterminal.api.BluetoothProximityDiscoveryConfigurationApi +import mek.stripeterminal.api.CartApi +import mek.stripeterminal.api.CartLineItemApi +import mek.stripeterminal.api.ConnectionStatusApi +import mek.stripeterminal.api.DeviceTypeApi +import mek.stripeterminal.api.DiscoveryConfigurationApi +import mek.stripeterminal.api.HandoffDiscoveryConfigurationApi +import mek.stripeterminal.api.InternetDiscoveryConfigurationApi +import mek.stripeterminal.api.LocalMobileDiscoveryConfigurationApi +import mek.stripeterminal.api.LocationApi +import mek.stripeterminal.api.LocationStatusApi +import mek.stripeterminal.api.ReaderApi +import mek.stripeterminal.api.ReaderDisplayMessageApi +import mek.stripeterminal.api.ReaderEventApi +import mek.stripeterminal.api.ReaderInputOptionApi +import mek.stripeterminal.api.ReaderSoftwareUpdateApi +import mek.stripeterminal.api.UpdateComponentApi +import mek.stripeterminal.api.UpdateTimeEstimateApi +import mek.stripeterminal.api.UsbDiscoveryConfigurationApi +import mek.stripeterminal.microsecondsToSeconds +import mek.stripeterminal.toHashMap + +fun Reader.toApi(): ReaderApi { + return ReaderApi( + locationStatus = locationStatus.toApi(), + batteryLevel = batteryLevel?.toDouble() ?: -1.0, + deviceType = deviceType.toApi(), + simulated = isSimulated, + availableUpdate = availableUpdate?.hasFirmwareUpdate ?: false, + locationId = location?.id, + location = location?.toApi(), + label = label, + serialNumber = serialNumber!!, + ) +} + +fun LocationStatus.toApi(): LocationStatusApi? { + return when (this) { + LocationStatus.UNKNOWN -> null + LocationStatus.SET -> LocationStatusApi.SET + LocationStatus.NOT_SET -> LocationStatusApi.NOT_SET + } +} + +fun DeviceType.toApi(): DeviceTypeApi? { + return when (this) { + DeviceType.CHIPPER_1X -> DeviceTypeApi.CHIPPER1_X + DeviceType.CHIPPER_2X -> DeviceTypeApi.CHIPPER2_X + DeviceType.STRIPE_M2 -> DeviceTypeApi.STRIPE_M2 + DeviceType.COTS_DEVICE -> DeviceTypeApi.COTS_DEVICE + DeviceType.VERIFONE_P400 -> DeviceTypeApi.VERIFONE_P400 + DeviceType.WISECUBE -> DeviceTypeApi.WISE_CUBE + DeviceType.WISEPAD_3 -> DeviceTypeApi.WISE_PAD3 + DeviceType.WISEPAD_3S -> DeviceTypeApi.WISE_PAD3S + DeviceType.WISEPOS_E -> DeviceTypeApi.WISE_POS_E + DeviceType.WISEPOS_E_DEVKIT -> DeviceTypeApi.WISE_POS_E_DEVKIT + DeviceType.ETNA -> DeviceTypeApi.ETNA + DeviceType.STRIPE_S700 -> DeviceTypeApi.STRIPE_S700 + DeviceType.STRIPE_S700_DEVKIT -> DeviceTypeApi.STRIPE_S700_DEVKIT + DeviceType.UNKNOWN -> null + } +} + +fun Location.toApi(): LocationApi { + return LocationApi( + address = address?.toApi(), + displayName = displayName, + id = id, + livemode = livemode, + metadata = metadata?.toHashMap() ?: hashMapOf(), + ) +} + +fun Address.toApi(): AddressApi { + return AddressApi( + city = city, + country = country, + line1 = line1, + line2 = line2, + postalCode = postalCode, + state = state, + ) +} + +fun ReaderEvent.toApi(): ReaderEventApi { + return when (this) { + ReaderEvent.CARD_INSERTED -> ReaderEventApi.CARD_INSERTED + ReaderEvent.CARD_REMOVED -> ReaderEventApi.CARD_REMOVED + } +} + +fun ReaderDisplayMessage.toApi(): ReaderDisplayMessageApi { + return when (this) { + ReaderDisplayMessage.CHECK_MOBILE_DEVICE -> ReaderDisplayMessageApi.CHECK_MOBILE_DEVICE + ReaderDisplayMessage.RETRY_CARD -> ReaderDisplayMessageApi.RETRY_CARD + ReaderDisplayMessage.INSERT_CARD -> ReaderDisplayMessageApi.INSERT_CARD + ReaderDisplayMessage.INSERT_OR_SWIPE_CARD -> ReaderDisplayMessageApi.INSERT_OR_SWIPE_CARD + ReaderDisplayMessage.SWIPE_CARD -> ReaderDisplayMessageApi.SWIPE_CARD + ReaderDisplayMessage.REMOVE_CARD -> ReaderDisplayMessageApi.REMOVE_CARD + ReaderDisplayMessage.MULTIPLE_CONTACTLESS_CARDS_DETECTED -> + ReaderDisplayMessageApi.MULTIPLE_CONTACTLESS_CARDS_DETECTED + ReaderDisplayMessage.TRY_ANOTHER_READ_METHOD -> ReaderDisplayMessageApi.TRY_ANOTHER_READ_METHOD + ReaderDisplayMessage.TRY_ANOTHER_CARD -> ReaderDisplayMessageApi.TRY_ANOTHER_CARD + ReaderDisplayMessage.CARD_REMOVED_TOO_EARLY -> ReaderDisplayMessageApi.CARD_REMOVED_TOO_EARLY + } +} + +fun ReaderInputOptions.ReaderInputOption.toApi(): ReaderInputOptionApi? { + return when (this) { + ReaderInputOptions.ReaderInputOption.NONE -> null + ReaderInputOptions.ReaderInputOption.INSERT -> ReaderInputOptionApi.INSERT_CARD + ReaderInputOptions.ReaderInputOption.SWIPE -> ReaderInputOptionApi.SWIPE_CARD + ReaderInputOptions.ReaderInputOption.TAP -> ReaderInputOptionApi.TAP_CARD + ReaderInputOptions.ReaderInputOption.MANUAL_ENTRY -> ReaderInputOptionApi.MANUAL_ENTRY + } +} + +fun BatteryStatus.toApi(): BatteryStatusApi? { + return when (this) { + BatteryStatus.UNKNOWN -> null + BatteryStatus.CRITICAL -> BatteryStatusApi.CRITICAL + BatteryStatus.LOW -> BatteryStatusApi.LOW + BatteryStatus.NOMINAL -> BatteryStatusApi.NOMINAL + } +} + +fun ReaderSoftwareUpdate.toApi(): ReaderSoftwareUpdateApi { + return ReaderSoftwareUpdateApi( + components = components.map { it.toApi() }, + keyProfileName = keyProfileName, + onlyInstallRequiredUpdates = onlyInstallRequiredUpdates, + requiredAt = requiredAt.time, + settingsVersion = settingsVersion, + timeEstimate = timeEstimate.toApi(), + version = version, + ) +} + +fun ReaderSoftwareUpdate.UpdateComponent.toApi(): UpdateComponentApi { + return when (this) { + ReaderSoftwareUpdate.UpdateComponent.INCREMENTAL -> UpdateComponentApi.INCREMENTAL + ReaderSoftwareUpdate.UpdateComponent.FIRMWARE -> UpdateComponentApi.FIRMWARE + ReaderSoftwareUpdate.UpdateComponent.CONFIG -> UpdateComponentApi.CONFIG + ReaderSoftwareUpdate.UpdateComponent.KEYS -> UpdateComponentApi.KEYS + } +} + +fun ReaderSoftwareUpdate.UpdateTimeEstimate.toApi(): UpdateTimeEstimateApi { + return when (this) { + ReaderSoftwareUpdate.UpdateTimeEstimate.LESS_THAN_ONE_MINUTE -> + UpdateTimeEstimateApi.LESS_THAN_ONE_MINUTE + ReaderSoftwareUpdate.UpdateTimeEstimate.ONE_TO_TWO_MINUTES -> + UpdateTimeEstimateApi.ONE_TO_TWO_MINUTES + ReaderSoftwareUpdate.UpdateTimeEstimate.TWO_TO_FIVE_MINUTES -> + UpdateTimeEstimateApi.TWO_TO_FIVE_MINUTES + ReaderSoftwareUpdate.UpdateTimeEstimate.FIVE_TO_FIFTEEN_MINUTES -> + UpdateTimeEstimateApi.FIVE_TO_FIFTEEN_MINUTES + } +} + +// PARAMS + +fun DiscoveryConfigurationApi.toHost(): DiscoveryConfiguration? { + return when (this) { + is BluetoothDiscoveryConfigurationApi -> + DiscoveryConfiguration.BluetoothDiscoveryConfiguration( + isSimulated = isSimulated, + timeout = timeout?.let { microsecondsToSeconds(it) } ?: 0, + ) + is BluetoothProximityDiscoveryConfigurationApi -> null + is HandoffDiscoveryConfigurationApi -> DiscoveryConfiguration.HandoffDiscoveryConfiguration() + is InternetDiscoveryConfigurationApi -> + DiscoveryConfiguration.InternetDiscoveryConfiguration( + isSimulated = isSimulated, + location = locationId, + ) + is LocalMobileDiscoveryConfigurationApi -> + DiscoveryConfiguration.LocalMobileDiscoveryConfiguration( + isSimulated = isSimulated, + ) + is UsbDiscoveryConfigurationApi -> + DiscoveryConfiguration.UsbDiscoveryConfiguration( + isSimulated = isSimulated, + timeout = timeout?.let { microsecondsToSeconds(it) } ?: 0, + ) + } +} + +fun DeviceTypeApi.toHost(): DeviceType? { + return when (this) { + DeviceTypeApi.CHIPPER1_X -> DeviceType.CHIPPER_1X + DeviceTypeApi.CHIPPER2_X -> DeviceType.CHIPPER_2X + DeviceTypeApi.STRIPE_M2 -> DeviceType.STRIPE_M2 + DeviceTypeApi.COTS_DEVICE -> DeviceType.COTS_DEVICE + DeviceTypeApi.VERIFONE_P400 -> DeviceType.VERIFONE_P400 + DeviceTypeApi.WISE_CUBE -> DeviceType.WISECUBE + DeviceTypeApi.WISE_PAD3 -> DeviceType.WISEPAD_3 + DeviceTypeApi.WISE_PAD3S -> DeviceType.WISEPAD_3S + DeviceTypeApi.WISE_POS_E -> DeviceType.WISEPOS_E + DeviceTypeApi.WISE_POS_E_DEVKIT -> DeviceType.WISEPOS_E_DEVKIT + DeviceTypeApi.ETNA -> DeviceType.ETNA + DeviceTypeApi.STRIPE_S700 -> DeviceType.STRIPE_S700 + DeviceTypeApi.STRIPE_S700_DEVKIT -> DeviceType.STRIPE_S700_DEVKIT + DeviceTypeApi.APPLE_BUILT_IN -> null + } +} + +fun CartApi.toHost(): Cart { + return Cart.Builder( + currency = currency, + tax = tax, + total = total, + lineItems = lineItems.map { it.toHost() }, + ) + .build() +} + +fun CartLineItemApi.toHost(): CartLineItem { + return CartLineItem.Builder( + description = description, + quantity = quantity.toInt(), + amount = amount, + ) + .build() +} + +// EXTRA + +fun ConnectionStatus.toApi(): ConnectionStatusApi { + return when (this) { + ConnectionStatus.NOT_CONNECTED -> ConnectionStatusApi.NOT_CONNECTED + ConnectionStatus.CONNECTING -> ConnectionStatusApi.CONNECTING + ConnectionStatus.CONNECTED -> ConnectionStatusApi.CONNECTED + } +} diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/RefundMappings.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/RefundMappings.kt new file mode 100644 index 0000000..b6dc2bf --- /dev/null +++ b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/RefundMappings.kt @@ -0,0 +1,27 @@ +package mek.stripeterminal.mappings + +import com.stripe.stripeterminal.external.models.Refund +import mek.stripeterminal.api.RefundApi +import mek.stripeterminal.api.RefundStatusApi +import mek.stripeterminal.toHashMap + +fun Refund.toApi(): RefundApi { + return RefundApi( + id = id, + amount = amount!!, + chargeId = chargeId!!, + created = created!!, + currency = currency!!, + metadata = metadata?.toHashMap() ?: HashMap(), + reason = reason, + status = + when (status) { + "succeeded" -> RefundStatusApi.SUCCEEDED + "pending" -> RefundStatusApi.PENDING + "failed" -> RefundStatusApi.FAILED + else -> null + }, + paymentMethodDetails = paymentMethodDetails?.toApi(), + failureReason = failureReason, + ) +} diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/SetupIntentMappings.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/SetupIntentMappings.kt new file mode 100644 index 0000000..313ad36 --- /dev/null +++ b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/SetupIntentMappings.kt @@ -0,0 +1,95 @@ +package mek.stripeterminal.mappings + +import com.stripe.stripeterminal.external.models.SetupAttempt +import com.stripe.stripeterminal.external.models.SetupAttemptStatus +import com.stripe.stripeterminal.external.models.SetupIntent +import com.stripe.stripeterminal.external.models.SetupIntentCardPresentDetails +import com.stripe.stripeterminal.external.models.SetupIntentPaymentMethodDetails +import com.stripe.stripeterminal.external.models.SetupIntentStatus +import com.stripe.stripeterminal.external.models.SetupIntentUsage +import mek.stripeterminal.api.SetupAttemptApi +import mek.stripeterminal.api.SetupAttemptCardPresentDetailsApi +import mek.stripeterminal.api.SetupAttemptPaymentMethodDetailsApi +import mek.stripeterminal.api.SetupAttemptStatusApi +import mek.stripeterminal.api.SetupIntentApi +import mek.stripeterminal.api.SetupIntentStatusApi +import mek.stripeterminal.api.SetupIntentUsageApi +import mek.stripeterminal.toHashMap + +fun SetupIntent.toApi(): SetupIntentApi { + return SetupIntentApi( + id = id, + created = created, + customerId = customerId, + metadata = metadata.toHashMap(), + usage = usage!!.toApi(), + status = status!!.toApi(), + latestAttempt = latestAttempt?.toApi(), + ) +} + +fun SetupIntentUsage.toApi(): SetupIntentUsageApi { + return when (this) { + SetupIntentUsage.ON_SESSION -> SetupIntentUsageApi.ON_SESSION + SetupIntentUsage.OFF_SESSION -> SetupIntentUsageApi.OFF_SESSION + } +} + +fun SetupIntentStatus.toApi(): SetupIntentStatusApi { + return when (this) { + SetupIntentStatus.REQUIRES_PAYMENT_METHOD -> SetupIntentStatusApi.REQUIRES_PAYMENT_METHOD + SetupIntentStatus.REQUIRES_CONFIRMATION -> SetupIntentStatusApi.REQUIRES_CONFIRMATION + SetupIntentStatus.REQUIRES_ACTION -> SetupIntentStatusApi.REQUIRES_ACTION + SetupIntentStatus.PROCESSING -> SetupIntentStatusApi.PROCESSING + SetupIntentStatus.SUCCEEDED -> SetupIntentStatusApi.SUCCEEDED + SetupIntentStatus.CANCELLED -> SetupIntentStatusApi.CANCELLED + } +} + +fun SetupAttempt.toApi(): SetupAttemptApi { + return SetupAttemptApi( + id = id, + applicationId = applicationId, + created = created, + customerId = customerId, + onBehalfOf = onBehalfOfId, + paymentMethodId = paymentMethodId, + paymentMethodDetails = paymentMethodDetails.toApi(), + setupIntentId = setupIntentId!!, + status = status.toApi(), + ) +} + +fun SetupAttemptStatus.toApi(): SetupAttemptStatusApi { + return when (this) { + SetupAttemptStatus.REQUIRES_CONFIRMATION -> SetupAttemptStatusApi.REQUIRES_CONFIRMATION + SetupAttemptStatus.REQUIRES_ACTION -> SetupAttemptStatusApi.REQUIRES_ACTION + SetupAttemptStatus.PROCESSING -> SetupAttemptStatusApi.PROCESSING + SetupAttemptStatus.SUCCEEDED -> SetupAttemptStatusApi.SUCCEEDED + SetupAttemptStatus.FAILED -> SetupAttemptStatusApi.FAILED + SetupAttemptStatus.ABANDONED -> SetupAttemptStatusApi.ABANDONED + } +} + +fun SetupIntentPaymentMethodDetails.toApi(): SetupAttemptPaymentMethodDetailsApi { + return SetupAttemptPaymentMethodDetailsApi( + cardPresent = cardPresentDetails?.toApi(), + interacPresent = interacPresentDetails?.toApi(), + ) +} + +fun SetupIntentCardPresentDetails.toApi(): SetupAttemptCardPresentDetailsApi { + return SetupAttemptCardPresentDetailsApi( + emvAuthData = emvAuthData!!, + generatedCard = generatedCard!!, + ) +} + +// PARAMS + +fun SetupIntentUsageApi.toHost(): String { + return when (this) { + SetupIntentUsageApi.ON_SESSION -> "on_session" + SetupIntentUsageApi.OFF_SESSION -> "off_session" + } +} diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/TipMappings.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/TipMappings.kt index 2f9ac5d..2c04219 100644 --- a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/TipMappings.kt +++ b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/mappings/TipMappings.kt @@ -1,10 +1,18 @@ package mek.stripeterminal.mappings import com.stripe.stripeterminal.external.models.Tip +import com.stripe.stripeterminal.external.models.TippingConfiguration import mek.stripeterminal.api.TipApi +import mek.stripeterminal.api.TippingConfigurationApi fun Tip.toApi(): TipApi { return TipApi( amount = amount, ) } + +// PARAMS + +fun TippingConfigurationApi.toHost(): TippingConfiguration { + return TippingConfiguration.Builder().setEligibleAmount(eligibleAmount).build() +} diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/DiscoverReadersSubject.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/DiscoverReadersSubject.kt index a85ead7..7b70114 100644 --- a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/DiscoverReadersSubject.kt +++ b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/DiscoverReadersSubject.kt @@ -12,10 +12,10 @@ import mek.stripeterminal.api.ControllerSink import mek.stripeterminal.api.DiscoveryConfigurationApi import mek.stripeterminal.api.ReaderApi import mek.stripeterminal.api.TerminalExceptionCodeApi -import mek.stripeterminal.api.toApi -import mek.stripeterminal.api.toHost -import mek.stripeterminal.api.toPlatformError import mek.stripeterminal.createApiError +import mek.stripeterminal.mappings.toApi +import mek.stripeterminal.mappings.toHost +import mek.stripeterminal.mappings.toPlatformError import mek.stripeterminal.runOnMainThread class DiscoverReadersSubject { diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/ReaderDelegatePlugin.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/ReaderDelegatePlugin.kt index da178b0..31fdc29 100644 --- a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/ReaderDelegatePlugin.kt +++ b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/ReaderDelegatePlugin.kt @@ -10,7 +10,7 @@ import com.stripe.stripeterminal.external.models.ReaderInputOptions import com.stripe.stripeterminal.external.models.ReaderSoftwareUpdate import com.stripe.stripeterminal.external.models.TerminalException import mek.stripeterminal.api.TerminalHandlersApi -import mek.stripeterminal.api.toApi +import mek.stripeterminal.mappings.toApi import mek.stripeterminal.runOnMainThread class ReaderDelegatePlugin(private val _handlers: TerminalHandlersApi) : diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/ReaderReconnectionListenerPlugin.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/ReaderReconnectionListenerPlugin.kt index 684db4c..6599671 100644 --- a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/ReaderReconnectionListenerPlugin.kt +++ b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/ReaderReconnectionListenerPlugin.kt @@ -4,7 +4,7 @@ import com.stripe.stripeterminal.external.callable.Cancelable import com.stripe.stripeterminal.external.callable.ReaderReconnectionListener import com.stripe.stripeterminal.external.models.Reader import mek.stripeterminal.api.TerminalHandlersApi -import mek.stripeterminal.api.toApi +import mek.stripeterminal.mappings.toApi import mek.stripeterminal.runOnMainThread class ReaderReconnectionListenerPlugin(private val _handlers: TerminalHandlersApi) : diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/TerminalDelegatePlugin.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/TerminalDelegatePlugin.kt index 1032de2..19cba29 100644 --- a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/TerminalDelegatePlugin.kt +++ b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/TerminalDelegatePlugin.kt @@ -8,7 +8,7 @@ import com.stripe.stripeterminal.external.models.ConnectionTokenException import com.stripe.stripeterminal.external.models.PaymentStatus import com.stripe.stripeterminal.external.models.Reader import mek.stripeterminal.api.TerminalHandlersApi -import mek.stripeterminal.api.toApi +import mek.stripeterminal.mappings.toApi import mek.stripeterminal.runOnMainThread class TerminalDelegatePlugin(private val _handlers: TerminalHandlersApi) : diff --git a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/TerminalErrorHandler.kt b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/TerminalErrorHandler.kt index d63030b..71f5985 100644 --- a/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/TerminalErrorHandler.kt +++ b/stripe_terminal/android/src/main/kotlin/mek/stripeterminal/plugin/TerminalErrorHandler.kt @@ -3,7 +3,7 @@ package mek.stripeterminal.plugin import com.stripe.stripeterminal.external.callable.ErrorCallback import com.stripe.stripeterminal.external.models.TerminalException import mek.stripeterminal.api.PlatformError -import mek.stripeterminal.api.toPlatformError +import mek.stripeterminal.mappings.toPlatformError import mek.stripeterminal.runOnMainThread abstract class TerminalErrorHandler(private val handler: (error: PlatformError) -> Unit) : diff --git a/stripe_terminal/ios/Classes/Api/ToApiExtensions.swift b/stripe_terminal/ios/Classes/Api/ToApiExtensions.swift deleted file mode 100644 index c786c93..0000000 --- a/stripe_terminal/ios/Classes/Api/ToApiExtensions.swift +++ /dev/null @@ -1,808 +0,0 @@ -import Foundation -import StripeTerminal - -extension Location { - func toApi() -> LocationApi { - return LocationApi( - address: address?.toApi(), - displayName: displayName, - id: stripeId, - livemode: livemode, - metadata: metadata ?? [:] - ) - } -} - -extension Reader { - func toApi() -> ReaderApi { - return ReaderApi( - locationStatus: locationStatus.toApi(), - deviceType: deviceType.toApi(), - simulated: simulated, - locationId: locationId, - location: location?.toApi(), - serialNumber: serialNumber, - availableUpdate: availableUpdate != nil, - batteryLevel: batteryLevel?.doubleValue ?? -1.0, - label: label - ) - } -} - -extension PaymentIntentStatus { - func toApi() -> PaymentIntentStatusApi { - switch self { - case .requiresPaymentMethod: - return .requiresPaymentMethod - case .requiresConfirmation: - return .requiresConfirmation - case .requiresCapture: - return .requiresCapture - case .processing: - return .processing - case .canceled: - return .canceled - case .succeeded: - return .succeeded - case .requiresAction: - return .requiresAction - @unknown default: - fatalError("Not supported payment intent status: \(self)") - } - } -} - -extension Address { - func toApi() -> AddressApi? { - return AddressApi( - city: city, - country: country, - line1: line1, - line2: line2, - postalCode: postalCode, - state: state - ) - } -} - -extension ConnectionStatus { - func toApi() -> ConnectionStatusApi { - switch self { - case .notConnected: - return .notConnected - case .connected: - return .connected - case .connecting: - return .connecting - @unknown default: - fatalError("WTF") - } - } -} - -extension LocationStatus { - func toApi() -> LocationStatusApi? { - switch self { - case .unknown: - return nil - case .set: - return .set - case .notSet: - return .notSet - @unknown default: - fatalError("WTF") - } - } -} - -extension DeviceType { - func toApi() -> DeviceTypeApi { - switch self { - case .chipper2X: - return .chipper2X - case .verifoneP400: - return .verifoneP400 - case .wisePad3: - return .wisePad3 - case .stripeM2: - return .stripeM2 - case .wisePosE: - return .wisePosE - case .wisePosEDevKit: - return .wisePosEDevkit - case .etna: - return .etna - case .chipper1X: - return .chipper1X - case .wiseCube: - return .wiseCube - case .stripeS700: - return .stripeS700 - case .stripeS700DevKit: - return .stripeS700Devkit - case .appleBuiltIn: - return .appleBuiltIn - @unknown default: - fatalError("WTF") - } - } -} - -extension ReaderEvent { - func toApi() -> ReaderEventApi { - switch (self) { - case .cardInserted: - return .cardInserted - case .cardRemoved: - return .cardRemoved - @unknown default: - fatalError() - } - } -} - -extension ReaderDisplayMessage { - func toApi() -> ReaderDisplayMessageApi { - switch (self) { - case .retryCard: - return .retryCard - case .insertCard: - return .insertCard - case .insertOrSwipeCard: - return .insertOrSwipeCard - case .swipeCard: - return .swipeCard - case .removeCard: - return .removeCard - case .multipleContactlessCardsDetected: - return .multipleContactlessCardsDetected - case .tryAnotherReadMethod: - return .tryAnotherReadMethod - case .tryAnotherCard: - return .tryAnotherCard - case .cardRemovedTooEarly: - return .cardRemovedTooEarly - @unknown default: - fatalError() - } - } -} - -extension ReaderInputOptions { - func toApi() -> [ReaderInputOptionApi] { - var options: [ReaderInputOptionApi] = [] - if (contains(ReaderInputOptions.insertCard)) { options.append(ReaderInputOptionApi.insertCard) } - if (contains(ReaderInputOptions.swipeCard)) { options.append(ReaderInputOptionApi.swipeCard) } - if (contains(ReaderInputOptions.tapCard)) { options.append(ReaderInputOptionApi.tapCard) } - return options - } -} - -extension BatteryStatus { - func toApi() -> BatteryStatusApi? { - switch (self) { - case .critical: - return .critical - case .low: - return .low - case .nominal: - return .nominal - case .unknown: - return nil - @unknown default: - fatalError() - } - } -} - -extension ReaderSoftwareUpdate { - func toApi() -> ReaderSoftwareUpdateApi { - return ReaderSoftwareUpdateApi( - components: components.toApi(), - keyProfileName: nil, - onlyInstallRequiredUpdates: false, - requiredAt: requiredAt, - settingsVersion: nil, - timeEstimate: estimatedUpdateTime.toApi(), - version: deviceSoftwareVersion - ) - } -} - -extension UpdateComponent { - func toApi() -> [UpdateComponentApi] { - var components: [UpdateComponentApi] = [] - if (contains(UpdateComponent.incremental)) {components.append(UpdateComponentApi.incremental)} - if (contains(UpdateComponent.firmware)) {components.append(UpdateComponentApi.firmware)} - if (contains(UpdateComponent.config)) {components.append(UpdateComponentApi.config)} - if (contains(UpdateComponent.keys)) {components.append(UpdateComponentApi.keys)} - return components - } -} - -extension UpdateTimeEstimate { - func toApi() -> UpdateTimeEstimateApi { - switch self { - case .estimateLessThan1Minute: - return .lessThanOneMinute - case .estimate1To2Minutes: - return .oneToTwoMinutes - case .estimate2To5Minutes: - return .twoToFiveMinutes - case .estimate5To15Minutes: - return .fiveToFifteenMinutes - @unknown default: - fatalError("WTF") - } - } -} - - -extension PaymentStatus { - func toApi() -> PaymentStatusApi { - switch self { - case .notReady: - return .notReady - case .ready: - return .ready - case .waitingForInput: - return .waitingForInput - case .processing: - return .processing - @unknown default: - fatalError("WTF") - } - } -} - -extension CardPresentDetails { - func toApi() -> CardPresentDetailsApi { - return CardPresentDetailsApi( - brand: brand.toApi(), - country: country, - expMonth: expMonth, - expYear: expYear, - funding: funding.toApi(), - last4: last4, - cardholderName: cardholderName, - emvAuthData: emvAuthData, - generatedCard: generatedCard, - incrementalAuthorizationStatus: incrementalAuthorizationStatus.toApi(), - networks: networks?.toApi(), - receipt: receipt?.toApi() - ) - } -} - -extension SCPIncrementalAuthorizationStatus { - func toApi() -> IncrementalAuthorizationStatusApi? { - switch self { - case .unknown: - return nil - case .notSupported: - return .notSupported - case .supported: - return .supported - @unknown default: - fatalError() - } - } -} - -extension SCPNetworks { - func toApi() -> CardNetworksApi { - return CardNetworksApi( - available: available?.map { CardBrand(rawValue: Int(truncating: $0))!.toApi()! } ?? [], - preferred: nil - ) - } -} - -extension ReceiptDetails { - func toApi() -> ReceiptDetailsApi { - return ReceiptDetailsApi( - accountType: accountType, - applicationPreferredName: applicationPreferredName, - authorizationCode: authorizationCode, - authorizationResponseCode: authorizationResponseCode, - applicationCryptogram: applicationCryptogram, - dedicatedFileName: dedicatedFileName, - transactionStatusInformation: transactionStatusInformation, - terminalVerificationResults: terminalVerificationResults - ) - } -} - -extension CardBrand { - func toApi() -> CardBrandApi? { - switch self { - case .amex: - return .amex - case .dinersClub: - return .dinersClub - case .discover: - return .discover - case .JCB: - return .jcb - case .masterCard: - return .masterCard - case .unionPay: - return .unionPay - case .visa: - return .visa - case .unknown: - return nil - case .interac: - return .interac - case .eftposAu: - return .eftposAu - @unknown default: - fatalError("WTF") - } - } -} - -extension CardFundingType { - func toApi() -> CardFundingTypeApi? { - switch self { - case .credit: - return .credit - case .debit: - return .debit - case .prepaid: - return .prepaid - case .other: - return nil - @unknown default: - fatalError("WTF") - } - } -} - -extension PaymentIntent { - func toApi() -> PaymentIntentApi { - return PaymentIntentApi( - id: stripeId!, - created: created, - status: status.toApi(), - amount: Double(amount), - captureMethod: captureMethod.toApi(), - currency: currency, - metadata: metadata ?? [:], - charges: charges.map { $0.toApi() }, - paymentMethod: paymentMethod?.toApi(), - paymentMethodId: paymentMethodId, - amountDetails: amountDetails?.toApi(), - amountTip: amountTip != nil ? Double(truncating: amountTip!) : nil, - statementDescriptor: statementDescriptor, - statementDescriptorSuffix: statementDescriptorSuffix, - // Only Android - amountCapturable: nil, - amountReceived: nil, - applicationId: nil, - applicationFeeAmount: nil, - cancellationReason: nil, - canceledAt: nil, - clientSecret: nil, - confirmationMethod: nil, - customerId: nil, - description: description, - invoiceId: nil, - onBehalfOf: nil, - reviewId: nil, - receiptEmail: nil, - setupFutureUsage: nil, - transferGroup: nil - ) - } -} - -extension CaptureMethod { - func toApi() -> CaptureMethodApi { - switch self { - case .manual: - return CaptureMethodApi.manual - case .automatic: - return CaptureMethodApi.automatic - @unknown default: - fatalError("Not supported CaptureMethodApi '\(self)'") - } - } -} - -extension SetupIntent { - func toApi() -> SetupIntentApi { - return SetupIntentApi( - id : stripeId, - created: created, - customerId: customer, - metadata: metadata ?? [:], - usage: usage.toApi(), - status: status.toApi(), - latestAttempt: latestAttempt?.toApi() - ) - } -} - -extension SetupIntentUsage { - func toApi() -> SetupIntentUsageApi { - switch self { - case .offSession: - return .offSession - case .onSession: - return .onSession - @unknown default: - fatalError() - } - } -} - -extension SetupIntentStatus { - func toApi() -> SetupIntentStatusApi { - switch self { - case .requiresPaymentMethod: - return .requiresPaymentMethod - case .requiresConfirmation: - return .requiresConfirmation - case .requiresAction: - return .requiresAction - case .processing: - return .processing - case .canceled: - return .cancelled - case .succeeded: - return .succeeded - @unknown default: - fatalError() - } - } -} - -extension SetupAttempt { - func toApi() -> SetupAttemptApi { - let statusApi: SetupAttemptStatusApi - switch status { - case "requires_confirmation": - statusApi = .requiresConfirmation - case "requires_action": - statusApi = .requiresAction - case "processing": - statusApi = .processing - case "succeeded": - statusApi = .succeeded - case "failed": - statusApi = .failed - case "abandoned": - statusApi = .abandoned - default: - fatalError() - } - return SetupAttemptApi( - id : stripeId, - applicationId: application, - created: created, - customerId: customer, - onBehalfOf: onBehalfOf, - paymentMethodId: paymentMethod, - paymentMethodDetails: paymentMethodDetails?.toApi(), - setupIntentId: setupIntent, - status: statusApi - ) - } -} - -extension SetupAttemptPaymentMethodDetails { - func toApi() -> SetupAttemptPaymentMethodDetailsApi { - return SetupAttemptPaymentMethodDetailsApi( - cardPresent: cardPresent?.toApi(), - interacPresent: interacPresent?.toApi() - ) - } -} - -extension SetupAttemptCardPresentDetails { - func toApi() -> SetupAttemptCardPresentDetailsApi { - return SetupAttemptCardPresentDetailsApi( - emvAuthData: emvAuthData, - generatedCard: generatedCard - ) - } -} - -extension Refund { - func toApi() -> RefundApi { - return RefundApi( - id: stripeId, - amount: Int(amount), - chargeId: charge, - created: created, - currency: currency, - metadata: metadata, - reason: reason, - status: status.toApi(), - paymentMethodDetails: paymentMethodDetails?.toApi(), - failureReason: failureReason - ) - } -} - -extension PaymentMethodDetails { - func toApi() -> PaymentMethodDetailsApi { - return PaymentMethodDetailsApi( - cardPresent: cardPresent?.toApi(), - interacPresent: interacPresent?.toApi() - ) - } -} - -extension RefundStatus { - func toApi() -> RefundStatusApi? { - switch self { - case .succeeded: - return .succeeded - case .pending: - return .pending - case .failed: - return .failed - case .unknown: - return nil - @unknown default: - fatalError() - } - } -} - -extension TerminalExceptionApi { - func toPlatformError() -> PlatformError { - return PlatformError("mek_stripe_terminal", nil, serialize()) - } -} - -extension NSError { - func toPlatformError(apiError: Error? = nil, paymentIntent: PaymentIntent? = nil) -> PlatformError { - if (self.domain != "com.stripe-terminal") { - return PlatformError("\(self.domain):\(self.code)", self.localizedDescription, "\(self)") - } - let apiException = toApi(apiError: apiError, paymentIntent: paymentIntent) - return apiException.toPlatformError() - } - - func toApi(apiError: Error? = nil, paymentIntent: PaymentIntent? = nil) -> TerminalExceptionApi { - let code = self.toApiCode(); - return TerminalExceptionApi( - code: code ?? TerminalExceptionCodeApi.unknown, - message: localizedDescription, - stackTrace: nil, - paymentIntent: paymentIntent?.toApi(), - apiError: apiError?.localizedDescription - ) - } - - private func toApiCode() -> TerminalExceptionCodeApi? { - let error = ErrorCode(_nsError: self) - - switch error.code { - case .cancelFailedAlreadyCompleted: - // Ignore this error, the plugin does not allow you to undo an operation more than once - return nil - case .notConnectedToReader: - return .notConnectedToReader - case .alreadyConnectedToReader: - return .alreadyConnectedToReader - case .connectionTokenProviderCompletedWithNothing: - return nil - case .connectionTokenProviderCompletedWithNothingWhileForwarding: - return .connectionTokenProviderErrorWhileForwarding - case .confirmInvalidPaymentIntent: - return .confirmInvalidPaymentIntent - case .nilPaymentIntent: - return nil - case .nilSetupIntent: - return nil - case .nilRefundPaymentMethod: - return nil - case .invalidRefundParameters: - return .invalidParameter - case .invalidClientSecret: - return .invalidClientSecret - case .invalidDiscoveryConfiguration: - return nil - case .invalidReaderForUpdate: - return .invalidReaderForUpdate - case .unsupportedSDK: - return .unsupportedSdk - case .featureNotAvailableWithConnectedReader: - return .featureNotAvailableWithConnectedReader - case .featureNotAvailable: - return .featureNotEnabledOnAccount - case .invalidListLocationsLimitParameter: - return .invalidParameter - case .bluetoothConnectionInvalidLocationIdParameter: - return .invalidParameter - case .invalidRequiredParameter: - return .invalidRequiredParameter - case .invalidRequiredParameterOnBehalfOf: - return .invalidParameter - case .accountIdMismatchWhileForwarding: - return .accountIdMismatchWhileForwarding - case .updatePaymentIntentUnavailableWhileOffline: - return .updatePaymentIntentUnavailableWhileOffline - case .updatePaymentIntentUnavailableWhileOfflineModeEnabled: - return .updatePaymentIntentUnavailableWhileOfflineModeEnabled - case .forwardingTestModePaymentInLiveMode: - return .forwardingTestModePaymentInLiveMode - case .forwardingLiveModePaymentInTestMode: - return .forwardingLiveModePaymentInTestMode - case .readerConnectionConfigurationInvalid: - return .invalidParameter - case .readerTippingParameterInvalid: - return .invalidTipParameter - case .invalidLocationIdParameter: - return .invalidParameter - case .canceled: - return .canceled - case .locationServicesDisabled: - return .locationServicesDisabled - case .bluetoothDisabled: - return .bluetoothDisabled - case .bluetoothAccessDenied: - return .bluetoothPermissionDenied - case .bluetoothScanTimedOut: - return .bluetoothScanTimedOut - case .bluetoothLowEnergyUnsupported: - return .bluetoothLowEnergyUnsupported - case .readerSoftwareUpdateFailedBatteryLow: - return .readerSoftwareUpdateFailedBatteryLow - case .readerSoftwareUpdateFailedInterrupted: - return .readerSoftwareUpdateFailedInterrupted - case .readerSoftwareUpdateFailedExpiredUpdate: - return .readerSoftwareUpdateFailedExpiredUpdate - case .bluetoothConnectionFailedBatteryCriticallyLow: - return .bluetoothConnectionFailedBatteryCriticallyLow - case .cardInsertNotRead: - return .cardInsertNotRead - case .cardSwipeNotRead: - return .cardSwipeNotRead - case .cardReadTimedOut: - return .cardReadTimedOut - case .cardRemoved: - return .cardRemoved - case .cardLeftInReader: - return .cardLeftInReader - case .offlinePaymentsDatabaseTooLarge: - return .offlinePaymentsDatabaseTooLarge - case .readerConnectionNotAvailableOffline: - return .readerConnectionNotAvailableOffline - case .readerConnectionOfflineLocationMismatch: - return .readerConnectionOfflineLocationMismatch - case .readerConnectionOfflineNeedsUpdate: - return .readerConnectionOfflineNeedsUpdate - case .noLastSeenAccount: - return .noLastSeenAccount - case .amountExceedsMaxOfflineAmount: - return .amountExceedsMaxOfflineAmount - case .invalidOfflineCurrency: - return .invalidOfflineCurrency - case .missingEMVData: - return .missingEmvData - case .commandNotAllowed: - return .commandNotAllowed - case .unsupportedMobileDeviceConfiguration: - return .unsupportedMobileDeviceConfiguration - case .passcodeNotEnabled: - return .passcodeNotEnabled - case .commandNotAllowedDuringCall: - return .commandNotAllowedDuringCall - case .invalidAmount: - return .invalidAmount - case .invalidCurrency: - return .invalidCurrency - case .appleBuiltInReaderTOSAcceptanceRequiresiCloudSignIn: - return .appleBuiltInReaderTOSAcceptanceRequiresiCloudSignIn - case .appleBuiltInReaderTOSAcceptanceCanceled: - return .appleBuiltInReaderTOSAcceptanceCanceled - case .readerBusy: - return .readerBusy - case .incompatibleReader: - return .incompatibleReader - case .readerCommunicationError: - return .readerCommunicationError - case .nfcDisabled: - return .nfcDisabled - case .bluetoothError: - return .bluetoothError - case .bluetoothConnectTimedOut: - return .bluetoothConnectTimedOut - case .bluetoothDisconnected: - return .bluetoothDisconnected - case .bluetoothPeerRemovedPairingInformation: - return .bluetoothPeerRemovedPairingInformation - case .bluetoothAlreadyPairedWithAnotherDevice: - return .bluetoothAlreadyPairedWithAnotherDevice - case .readerSoftwareUpdateFailed: - return .readerSoftwareUpdateFailed - case .readerSoftwareUpdateFailedReaderError: - return .readerSoftwareUpdateFailedReaderError - case .readerSoftwareUpdateFailedServerError: - return .readerSoftwareUpdateFailedServerError - case .unsupportedReaderVersion: - return .unsupportedReaderVersion - case .unknownReaderIpAddress: - return .unknownReaderIpAddress - case .internetConnectTimeOut: - return .internetConnectTimeOut - case .connectFailedReaderIsInUse: - return .connectFailedReaderIsInUse - case .bluetoothReconnectStarted: - return .bluetoothReconnectStarted - case .readerNotAccessibleInBackground: - return .readerNotAccessibleInBackground - case .appleBuiltInReaderFailedToPrepare: - return .appleBuiltInReaderFailedToPrepare - case .appleBuiltInReaderDeviceBanned: - return .appleBuiltInReaderDeviceBanned - case .appleBuiltInReaderTOSNotYetAccepted: - return .appleBuiltInReaderTOSNotYetAccepted - case .appleBuiltInReaderTOSAcceptanceFailed: - return .appleBuiltInReaderTOSAcceptanceFailed - case .appleBuiltInReaderMerchantBlocked: - return .appleBuiltInReaderMerchantBlocked - case .appleBuiltInReaderInvalidMerchant: - return .appleBuiltInReaderInvalidMerchant - case .unexpectedSdkError: - return .unexpectedSdkError - case .unexpectedReaderError: - return .unexpectedReaderError - case .encryptionKeyFailure: - return .encryptionKeyFailure - case .encryptionKeyStillInitializing: - return .encryptionKeyStillInitializing - case .declinedByStripeAPI: - return .declinedByStripeApi - case .declinedByReader: - return .declinedByReader - case .commandRequiresCardholderConsent: - return .customerConsentRequired - case .refundFailed: - return .refundFailed - case .cardSwipeNotAvailable: - return .cardSwipeNotAvailable - case .interacNotSupportedOffline: - return .interacNotSupportedOffline - case .offlineAndCardExpired: - return .offlineAndCardExpired - case .offlineTransactionDeclined: - return .offlineTransactionDeclined - case .offlineCollectAndConfirmMismatch: - return .offlineCollectAndConfirmMismatch - case .onlinePinNotSupportedOffline: - return .onlinePinNotSupportedOffline - case .offlineTestCardInLivemode: - return .testCardInLiveMode - case .notConnectedToInternet: - return .notConnectedToInternet - case .requestTimedOut: - return .requestTimedOut - case .stripeAPIError: - return .stripeApiError - case .stripeAPIResponseDecodingError: - return .stripeApiResponseDecodingError - case .internalNetworkError: - return .internalNetworkError - case .connectionTokenProviderCompletedWithError: - return .connectionTokenProviderError - case .connectionTokenProviderCompletedWithErrorWhileForwarding: - return .connectionTokenProviderErrorWhileForwarding - case .connectionTokenProviderTimedOut: - return .connectionTokenProviderTimedOut - case .sessionExpired: - return .sessionExpired - case .notConnectedToInternetAndOfflineBehaviorRequireOnline: - return .notConnectedToInternetAndOfflineBehaviorRequireOnline - case .offlineBehaviorForceOfflineWithFeatureDisabled: - return .offlineBehaviorForceOfflineWithFeatureDisabled - @unknown default: - fatalError() - } - } -} diff --git a/stripe_terminal/ios/Classes/Api/ToHostExtensions.swift b/stripe_terminal/ios/Classes/Api/ToHostExtensions.swift deleted file mode 100644 index 6ad91df..0000000 --- a/stripe_terminal/ios/Classes/Api/ToHostExtensions.swift +++ /dev/null @@ -1,242 +0,0 @@ -import Foundation -import StripeTerminal - -extension PaymentIntentParametersApi { - func toHost() throws -> PaymentIntentParameters { - let b = PaymentIntentParametersBuilder( - amount: UInt(amount), - currency: currency - ) - .setPaymentMethodTypes(paymentMethodTypes.map { $0.toHost() }) - .setCaptureMethod(captureMethod.toHost()) - .setMetadata(metadata) - .setStripeDescription(description) - .setStatementDescriptor(statementDescriptor) - .setStatementDescriptorSuffix(statementDescriptorSuffix) - .setReceiptEmail(receiptEmail) - .setCustomer(customerId) - .setApplicationFeeAmount(applicationFeeAmount?.nsNumberValue) - .setTransferDataDestination(transferDataDestination) - .setTransferGroup(transferGroup) - .setOnBehalfOf(onBehalfOf) - .setSetupFutureUsage(setupFutureUsage?.toHost()) - if let it = paymentMethodOptionsParameters { b.setPaymentMethodOptionsParameters(try it.toHost()) } - return try b.build() - } -} - -extension TippingConfigurationApi { - func toHost() throws -> TippingConfiguration { - return try TippingConfigurationBuilder() - .setEligibleAmount(eligibleAmount) - .build() - } -} - -extension PaymentMethodOptionsParametersApi { - func toHost() throws -> PaymentMethodOptionsParameters { - return try PaymentMethodOptionsParametersBuilder( - cardPresentParameters: try cardPresentParameters.toHost() - ) - .build() - } -} - -extension CardPresentParametersApi { - func toHost() throws -> CardPresentParameters { - let b = CardPresentParametersBuilder() - if let it = captureMethod { b.setCaptureMethod(it.toHost()) } - if let it = requestedPriority { b.setRequestedPriority(it.toHost()) } - if let it = requestExtendedAuthorization { b.setRequestExtendedAuthorization(it) } - if let it = requestIncrementalAuthorizationSupport { b.setRequestIncrementalAuthorizationSupport(it) } - return try b.build() - } -} - -extension CardPresentCaptureMethodApi { - func toHost() -> CardPresentCaptureMethod { - switch self { - case .manualPreferred: - return .manualPreferred - } - } -} - -extension CardPresentRoutingApi { - func toHost() -> CardPresentRouting { - switch self { - case .domestic: - return .domestic - case .international: - return .international - } - } -} - -extension PaymentMethodTypeApi { - func toHost() -> String { - switch (self) { - case .cardPresent: - return "card_present" - case .card: - return "card" - case .interactPresent: - return "interact_present" - } - } -} - -extension CaptureMethodApi { - func toHost() -> CaptureMethod { - switch self { - case .automatic: - return .automatic - case .manual: - return .manual - } - } -} - -extension PaymentIntentUsageApi { - func toHost() -> String { - switch self { - case .offSession: - return "off_session" - case .onSession: - return "on_session" - } - } -} - -extension DiscoveryConfigurationApi { - func toHost() throws -> DiscoveryConfiguration? { - switch self { - case let config as BluetoothDiscoveryConfigurationApi: - return try BluetoothScanDiscoveryConfigurationBuilder() - .setTimeout(UInt(config.timeout ?? 0)) - .setSimulated(config.isSimulated) - .build() - case let config as BluetoothProximityDiscoveryConfigurationApi: - return try BluetoothProximityDiscoveryConfigurationBuilder() - .setSimulated(config.isSimulated) - .build() - case _ as HandoffDiscoveryConfigurationApi: - return nil - case let config as InternetDiscoveryConfigurationApi: - return try InternetDiscoveryConfigurationBuilder() - .setSimulated(config.isSimulated) - .setLocationId(config.locationId) - .build() - case let config as LocalMobileDiscoveryConfigurationApi: - return try LocalMobileDiscoveryConfigurationBuilder() - .setSimulated(config.isSimulated) - .build() - case _ as UsbDiscoveryConfigurationApi: - return nil - default: - fatalError() - } - } - - func toHostDiscoveryMethod() -> DiscoveryMethod? { - switch self { - case _ as BluetoothDiscoveryConfigurationApi: - return .bluetoothScan - case _ as BluetoothProximityDiscoveryConfigurationApi: - return .bluetoothProximity - case _ as HandoffDiscoveryConfigurationApi: - return nil - case _ as InternetDiscoveryConfigurationApi: - return .internet - case _ as LocalMobileDiscoveryConfigurationApi: - return .localMobile - case _ as UsbDiscoveryConfigurationApi: - return nil - default: - fatalError() - } - } - - func toHostSimulated() -> Bool { - switch self { - case let config as BluetoothDiscoveryConfigurationApi: - return config.isSimulated - case let config as BluetoothProximityDiscoveryConfigurationApi: - return config.isSimulated - case _ as HandoffDiscoveryConfigurationApi: - return false - case let config as InternetDiscoveryConfigurationApi: - return config.isSimulated - case let config as LocalMobileDiscoveryConfigurationApi: - return config.isSimulated - case _ as UsbDiscoveryConfigurationApi: - return false - default: - fatalError() - } - } -} - -extension DeviceTypeApi { - func toHost() -> DeviceType? { - switch self { - case .chipper2X: - return .chipper2X - case .verifoneP400: - return .verifoneP400 - case .wisePad3: - return .wisePad3 - case .stripeM2: - return .stripeM2 - case .wisePosE: - return .wisePosE - case .wisePosEDevkit: - return .wisePosEDevKit - case .etna: - return .etna - case .chipper1X: - return .chipper1X - case .wiseCube: - return .wiseCube - case .stripeS700: - return .stripeS700 - case .stripeS700Devkit: - return .stripeS700DevKit - case .appleBuiltIn: - return .appleBuiltIn - case .cotsDevice, .wisePad3s: - return nil - } - } -} - - -extension CartApi { - func toHost() throws -> Cart { - return try CartBuilder(currency: currency) - .setTax(tax) - .setTotal(total) - .setLineItems(lineItems.map { try $0.toHost()} ) - .build() - } -} - -extension CartLineItemApi { - func toHost() throws -> CartLineItem { - return try CartLineItemBuilder(displayName: description) - .setAmount(amount) - .setQuantity(quantity) - .build() - } -} - -extension SetupIntentUsageApi { - func toHost() -> SetupIntentUsage { - switch self { - case .offSession: - return .offSession - case .onSession: - return .onSession - } - } -} diff --git a/stripe_terminal/ios/Classes/Mappings/CardMappings.swift b/stripe_terminal/ios/Classes/Mappings/CardMappings.swift index 6d930c2..a7e4532 100644 --- a/stripe_terminal/ios/Classes/Mappings/CardMappings.swift +++ b/stripe_terminal/ios/Classes/Mappings/CardMappings.swift @@ -13,3 +13,141 @@ extension CardDetails { ) } } + +extension CardBrand { + func toApi() -> CardBrandApi? { + switch self { + case .amex: + return .amex + case .dinersClub: + return .dinersClub + case .discover: + return .discover + case .JCB: + return .jcb + case .masterCard: + return .masterCard + case .unionPay: + return .unionPay + case .visa: + return .visa + case .unknown: + return nil + case .interac: + return .interac + case .eftposAu: + return .eftposAu + @unknown default: + fatalError("WTF") + } + } +} + +extension CardFundingType { + func toApi() -> CardFundingTypeApi? { + switch self { + case .credit: + return .credit + case .debit: + return .debit + case .prepaid: + return .prepaid + case .other: + return nil + @unknown default: + fatalError("WTF") + } + } +} + + +extension CardPresentDetails { + func toApi() -> CardPresentDetailsApi { + return CardPresentDetailsApi( + brand: brand.toApi(), + country: country, + expMonth: expMonth, + expYear: expYear, + funding: funding.toApi(), + last4: last4, + cardholderName: cardholderName, + emvAuthData: emvAuthData, + generatedCard: generatedCard, + incrementalAuthorizationStatus: incrementalAuthorizationStatus.toApi(), + networks: networks?.toApi(), + receipt: receipt?.toApi() + ) + } +} + +extension SCPIncrementalAuthorizationStatus { + func toApi() -> IncrementalAuthorizationStatusApi? { + switch self { + case .unknown: + return nil + case .notSupported: + return .notSupported + case .supported: + return .supported + @unknown default: + fatalError() + } + } +} + +extension SCPNetworks { + func toApi() -> CardNetworksApi { + return CardNetworksApi( + available: available?.map { CardBrand(rawValue: Int(truncating: $0))!.toApi()! } ?? [], + preferred: nil + ) + } +} + +extension ReceiptDetails { + func toApi() -> ReceiptDetailsApi { + return ReceiptDetailsApi( + accountType: accountType, + applicationPreferredName: applicationPreferredName, + authorizationCode: authorizationCode, + authorizationResponseCode: authorizationResponseCode, + applicationCryptogram: applicationCryptogram, + dedicatedFileName: dedicatedFileName, + transactionStatusInformation: transactionStatusInformation, + terminalVerificationResults: terminalVerificationResults + ) + } +} + +// PARAMS + +extension CardPresentParametersApi { + func toHost() throws -> CardPresentParameters { + let b = CardPresentParametersBuilder() + if let it = captureMethod { b.setCaptureMethod(it.toHost()) } + if let it = requestedPriority { b.setRequestedPriority(it.toHost()) } + if let it = requestExtendedAuthorization { b.setRequestExtendedAuthorization(it) } + if let it = requestIncrementalAuthorizationSupport { b.setRequestIncrementalAuthorizationSupport(it) } + return try b.build() + } +} + +extension CardPresentCaptureMethodApi { + func toHost() -> CardPresentCaptureMethod { + switch self { + case .manualPreferred: + return .manualPreferred + } + } +} + +extension CardPresentRoutingApi { + func toHost() -> CardPresentRouting { + switch self { + case .domestic: + return .domestic + case .international: + return .international + } + } +} diff --git a/stripe_terminal/ios/Classes/Mappings/ExceptionMappings.swift b/stripe_terminal/ios/Classes/Mappings/ExceptionMappings.swift new file mode 100644 index 0000000..78248a6 --- /dev/null +++ b/stripe_terminal/ios/Classes/Mappings/ExceptionMappings.swift @@ -0,0 +1,257 @@ +import Foundation +import StripeTerminal + +extension TerminalExceptionApi { + func toPlatformError() -> PlatformError { + return PlatformError("mek_stripe_terminal", nil, serialize()) + } +} + +extension NSError { + func toPlatformError(apiError: Error? = nil, paymentIntent: PaymentIntent? = nil) -> PlatformError { + if (self.domain != "com.stripe-terminal") { + return PlatformError("\(self.domain):\(self.code)", self.localizedDescription, "\(self)") + } + let apiException = toApi(apiError: apiError, paymentIntent: paymentIntent) + return apiException.toPlatformError() + } + + func toApi(apiError: Error? = nil, paymentIntent: PaymentIntent? = nil) -> TerminalExceptionApi { + let code = self.toApiCode(); + return TerminalExceptionApi( + code: code ?? TerminalExceptionCodeApi.unknown, + message: localizedDescription, + stackTrace: nil, + paymentIntent: paymentIntent?.toApi(), + apiError: apiError?.localizedDescription + ) + } + + private func toApiCode() -> TerminalExceptionCodeApi? { + let error = ErrorCode(_nsError: self) + + switch error.code { + case .cancelFailedAlreadyCompleted: + // Ignore this error, the plugin does not allow you to undo an operation more than once + return nil + case .notConnectedToReader: + return .notConnectedToReader + case .alreadyConnectedToReader: + return .alreadyConnectedToReader + case .connectionTokenProviderCompletedWithNothing: + return nil + case .connectionTokenProviderCompletedWithNothingWhileForwarding: + return .connectionTokenProviderErrorWhileForwarding + case .confirmInvalidPaymentIntent: + return .confirmInvalidPaymentIntent + case .nilPaymentIntent: + return nil + case .nilSetupIntent: + return nil + case .nilRefundPaymentMethod: + return nil + case .invalidRefundParameters: + return .invalidParameter + case .invalidClientSecret: + return .invalidClientSecret + case .invalidDiscoveryConfiguration: + return nil + case .invalidReaderForUpdate: + return .invalidReaderForUpdate + case .unsupportedSDK: + return .unsupportedSdk + case .featureNotAvailableWithConnectedReader: + return .featureNotAvailableWithConnectedReader + case .featureNotAvailable: + return .featureNotEnabledOnAccount + case .invalidListLocationsLimitParameter: + return .invalidParameter + case .bluetoothConnectionInvalidLocationIdParameter: + return .invalidParameter + case .invalidRequiredParameter: + return .invalidRequiredParameter + case .invalidRequiredParameterOnBehalfOf: + return .invalidParameter + case .accountIdMismatchWhileForwarding: + return .accountIdMismatchWhileForwarding + case .updatePaymentIntentUnavailableWhileOffline: + return .updatePaymentIntentUnavailableWhileOffline + case .updatePaymentIntentUnavailableWhileOfflineModeEnabled: + return .updatePaymentIntentUnavailableWhileOfflineModeEnabled + case .forwardingTestModePaymentInLiveMode: + return .forwardingTestModePaymentInLiveMode + case .forwardingLiveModePaymentInTestMode: + return .forwardingLiveModePaymentInTestMode + case .readerConnectionConfigurationInvalid: + return .invalidParameter + case .readerTippingParameterInvalid: + return .invalidTipParameter + case .invalidLocationIdParameter: + return .invalidParameter + case .canceled: + return .canceled + case .locationServicesDisabled: + return .locationServicesDisabled + case .bluetoothDisabled: + return .bluetoothDisabled + case .bluetoothAccessDenied: + return .bluetoothPermissionDenied + case .bluetoothScanTimedOut: + return .bluetoothScanTimedOut + case .bluetoothLowEnergyUnsupported: + return .bluetoothLowEnergyUnsupported + case .readerSoftwareUpdateFailedBatteryLow: + return .readerSoftwareUpdateFailedBatteryLow + case .readerSoftwareUpdateFailedInterrupted: + return .readerSoftwareUpdateFailedInterrupted + case .readerSoftwareUpdateFailedExpiredUpdate: + return .readerSoftwareUpdateFailedExpiredUpdate + case .bluetoothConnectionFailedBatteryCriticallyLow: + return .bluetoothConnectionFailedBatteryCriticallyLow + case .cardInsertNotRead: + return .cardInsertNotRead + case .cardSwipeNotRead: + return .cardSwipeNotRead + case .cardReadTimedOut: + return .cardReadTimedOut + case .cardRemoved: + return .cardRemoved + case .cardLeftInReader: + return .cardLeftInReader + case .offlinePaymentsDatabaseTooLarge: + return .offlinePaymentsDatabaseTooLarge + case .readerConnectionNotAvailableOffline: + return .readerConnectionNotAvailableOffline + case .readerConnectionOfflineLocationMismatch: + return .readerConnectionOfflineLocationMismatch + case .readerConnectionOfflineNeedsUpdate: + return .readerConnectionOfflineNeedsUpdate + case .noLastSeenAccount: + return .noLastSeenAccount + case .amountExceedsMaxOfflineAmount: + return .amountExceedsMaxOfflineAmount + case .invalidOfflineCurrency: + return .invalidOfflineCurrency + case .missingEMVData: + return .missingEmvData + case .commandNotAllowed: + return .commandNotAllowed + case .unsupportedMobileDeviceConfiguration: + return .unsupportedMobileDeviceConfiguration + case .passcodeNotEnabled: + return .passcodeNotEnabled + case .commandNotAllowedDuringCall: + return .commandNotAllowedDuringCall + case .invalidAmount: + return .invalidAmount + case .invalidCurrency: + return .invalidCurrency + case .appleBuiltInReaderTOSAcceptanceRequiresiCloudSignIn: + return .appleBuiltInReaderTOSAcceptanceRequiresiCloudSignIn + case .appleBuiltInReaderTOSAcceptanceCanceled: + return .appleBuiltInReaderTOSAcceptanceCanceled + case .readerBusy: + return .readerBusy + case .incompatibleReader: + return .incompatibleReader + case .readerCommunicationError: + return .readerCommunicationError + case .nfcDisabled: + return .nfcDisabled + case .bluetoothError: + return .bluetoothError + case .bluetoothConnectTimedOut: + return .bluetoothConnectTimedOut + case .bluetoothDisconnected: + return .bluetoothDisconnected + case .bluetoothPeerRemovedPairingInformation: + return .bluetoothPeerRemovedPairingInformation + case .bluetoothAlreadyPairedWithAnotherDevice: + return .bluetoothAlreadyPairedWithAnotherDevice + case .readerSoftwareUpdateFailed: + return .readerSoftwareUpdateFailed + case .readerSoftwareUpdateFailedReaderError: + return .readerSoftwareUpdateFailedReaderError + case .readerSoftwareUpdateFailedServerError: + return .readerSoftwareUpdateFailedServerError + case .unsupportedReaderVersion: + return .unsupportedReaderVersion + case .unknownReaderIpAddress: + return .unknownReaderIpAddress + case .internetConnectTimeOut: + return .internetConnectTimeOut + case .connectFailedReaderIsInUse: + return .connectFailedReaderIsInUse + case .bluetoothReconnectStarted: + return .bluetoothReconnectStarted + case .readerNotAccessibleInBackground: + return .readerNotAccessibleInBackground + case .appleBuiltInReaderFailedToPrepare: + return .appleBuiltInReaderFailedToPrepare + case .appleBuiltInReaderDeviceBanned: + return .appleBuiltInReaderDeviceBanned + case .appleBuiltInReaderTOSNotYetAccepted: + return .appleBuiltInReaderTOSNotYetAccepted + case .appleBuiltInReaderTOSAcceptanceFailed: + return .appleBuiltInReaderTOSAcceptanceFailed + case .appleBuiltInReaderMerchantBlocked: + return .appleBuiltInReaderMerchantBlocked + case .appleBuiltInReaderInvalidMerchant: + return .appleBuiltInReaderInvalidMerchant + case .unexpectedSdkError: + return .unexpectedSdkError + case .unexpectedReaderError: + return .unexpectedReaderError + case .encryptionKeyFailure: + return .encryptionKeyFailure + case .encryptionKeyStillInitializing: + return .encryptionKeyStillInitializing + case .declinedByStripeAPI: + return .declinedByStripeApi + case .declinedByReader: + return .declinedByReader + case .commandRequiresCardholderConsent: + return .customerConsentRequired + case .refundFailed: + return .refundFailed + case .cardSwipeNotAvailable: + return .cardSwipeNotAvailable + case .interacNotSupportedOffline: + return .interacNotSupportedOffline + case .offlineAndCardExpired: + return .offlineAndCardExpired + case .offlineTransactionDeclined: + return .offlineTransactionDeclined + case .offlineCollectAndConfirmMismatch: + return .offlineCollectAndConfirmMismatch + case .onlinePinNotSupportedOffline: + return .onlinePinNotSupportedOffline + case .offlineTestCardInLivemode: + return .testCardInLiveMode + case .notConnectedToInternet: + return .notConnectedToInternet + case .requestTimedOut: + return .requestTimedOut + case .stripeAPIError: + return .stripeApiError + case .stripeAPIResponseDecodingError: + return .stripeApiResponseDecodingError + case .internalNetworkError: + return .internalNetworkError + case .connectionTokenProviderCompletedWithError: + return .connectionTokenProviderError + case .connectionTokenProviderCompletedWithErrorWhileForwarding: + return .connectionTokenProviderErrorWhileForwarding + case .connectionTokenProviderTimedOut: + return .connectionTokenProviderTimedOut + case .sessionExpired: + return .sessionExpired + case .notConnectedToInternetAndOfflineBehaviorRequireOnline: + return .notConnectedToInternetAndOfflineBehaviorRequireOnline + case .offlineBehaviorForceOfflineWithFeatureDisabled: + return .offlineBehaviorForceOfflineWithFeatureDisabled + @unknown default: + fatalError() + } + } +} diff --git a/stripe_terminal/ios/Classes/Mappings/PaymentIntentMappings.swift b/stripe_terminal/ios/Classes/Mappings/PaymentIntentMappings.swift index 7da5f3d..7480186 100644 --- a/stripe_terminal/ios/Classes/Mappings/PaymentIntentMappings.swift +++ b/stripe_terminal/ios/Classes/Mappings/PaymentIntentMappings.swift @@ -1,6 +1,80 @@ import Foundation import StripeTerminal +extension PaymentIntent { + func toApi() -> PaymentIntentApi { + return PaymentIntentApi( + id: stripeId!, + created: created, + status: status.toApi(), + amount: Double(amount), + captureMethod: captureMethod.toApi(), + currency: currency, + metadata: metadata ?? [:], + charges: charges.map { $0.toApi() }, + paymentMethod: paymentMethod?.toApi(), + paymentMethodId: paymentMethodId, + amountDetails: amountDetails?.toApi(), + amountTip: amountTip != nil ? Double(truncating: amountTip!) : nil, + statementDescriptor: statementDescriptor, + statementDescriptorSuffix: statementDescriptorSuffix, + // Only Android + amountCapturable: nil, + amountReceived: nil, + applicationId: nil, + applicationFeeAmount: nil, + cancellationReason: nil, + canceledAt: nil, + clientSecret: nil, + confirmationMethod: nil, + customerId: nil, + description: description, + invoiceId: nil, + onBehalfOf: nil, + reviewId: nil, + receiptEmail: nil, + setupFutureUsage: nil, + transferGroup: nil + ) + } +} + +extension PaymentIntentStatus { + func toApi() -> PaymentIntentStatusApi { + switch self { + case .requiresPaymentMethod: + return .requiresPaymentMethod + case .requiresConfirmation: + return .requiresConfirmation + case .requiresCapture: + return .requiresCapture + case .processing: + return .processing + case .canceled: + return .canceled + case .succeeded: + return .succeeded + case .requiresAction: + return .requiresAction + @unknown default: + fatalError("Not supported payment intent status: \(self)") + } + } +} + +extension CaptureMethod { + func toApi() -> CaptureMethodApi { + switch self { + case .manual: + return CaptureMethodApi.manual + case .automatic: + return CaptureMethodApi.automatic + @unknown default: + fatalError("Not supported CaptureMethodApi '\(self)'") + } + } +} + extension SCPAmountDetails { func toApi() -> AmountDetailsApi { return AmountDetailsApi( @@ -8,3 +82,84 @@ extension SCPAmountDetails { ) } } + +// PARAMS + + +extension PaymentIntentParametersApi { + func toHost() throws -> PaymentIntentParameters { + let b = PaymentIntentParametersBuilder( + amount: UInt(amount), + currency: currency + ) + .setPaymentMethodTypes(paymentMethodTypes.map { $0.toHost() }) + .setCaptureMethod(captureMethod.toHost()) + .setMetadata(metadata) + .setStripeDescription(description) + .setStatementDescriptor(statementDescriptor) + .setStatementDescriptorSuffix(statementDescriptorSuffix) + .setReceiptEmail(receiptEmail) + .setCustomer(customerId) + .setApplicationFeeAmount(applicationFeeAmount?.nsNumberValue) + .setTransferDataDestination(transferDataDestination) + .setTransferGroup(transferGroup) + .setOnBehalfOf(onBehalfOf) + .setSetupFutureUsage(setupFutureUsage?.toHost()) + if let it = paymentMethodOptionsParameters { b.setPaymentMethodOptionsParameters(try it.toHost()) } + return try b.build() + } +} + +extension PaymentMethodTypeApi { + func toHost() -> String { + switch (self) { + case .cardPresent: + return "card_present" + case .card: + return "card" + case .interactPresent: + return "interact_present" + } + } +} + +extension CaptureMethodApi { + func toHost() -> CaptureMethod { + switch self { + case .automatic: + return .automatic + case .manual: + return .manual + } + } +} + +extension PaymentIntentUsageApi { + func toHost() -> String { + switch self { + case .offSession: + return "off_session" + case .onSession: + return "on_session" + } + } +} + +// EXTRA + +extension PaymentStatus { + func toApi() -> PaymentStatusApi { + switch self { + case .notReady: + return .notReady + case .ready: + return .ready + case .waitingForInput: + return .waitingForInput + case .processing: + return .processing + @unknown default: + fatalError("WTF") + } + } +} diff --git a/stripe_terminal/ios/Classes/Mappings/PaymentMethodMappings.swift b/stripe_terminal/ios/Classes/Mappings/PaymentMethodMappings.swift index c778001..c51d228 100644 --- a/stripe_terminal/ios/Classes/Mappings/PaymentMethodMappings.swift +++ b/stripe_terminal/ios/Classes/Mappings/PaymentMethodMappings.swift @@ -13,3 +13,14 @@ extension PaymentMethod { ) } } + +// PARAMS + +extension PaymentMethodOptionsParametersApi { + func toHost() throws -> PaymentMethodOptionsParameters { + return try PaymentMethodOptionsParametersBuilder( + cardPresentParameters: try cardPresentParameters.toHost() + ) + .build() + } +} diff --git a/stripe_terminal/ios/Classes/Mappings/ReaderMappings.swift b/stripe_terminal/ios/Classes/Mappings/ReaderMappings.swift new file mode 100644 index 0000000..df586dd --- /dev/null +++ b/stripe_terminal/ios/Classes/Mappings/ReaderMappings.swift @@ -0,0 +1,344 @@ +import Foundation +import StripeTerminal + + +extension Reader { + func toApi() -> ReaderApi { + return ReaderApi( + locationStatus: locationStatus.toApi(), + deviceType: deviceType.toApi(), + simulated: simulated, + locationId: locationId, + location: location?.toApi(), + serialNumber: serialNumber, + availableUpdate: availableUpdate != nil, + batteryLevel: batteryLevel?.doubleValue ?? -1.0, + label: label + ) + } +} + +extension Location { + func toApi() -> LocationApi { + return LocationApi( + address: address?.toApi(), + displayName: displayName, + id: stripeId, + livemode: livemode, + metadata: metadata ?? [:] + ) + } +} + + +extension Address { + func toApi() -> AddressApi? { + return AddressApi( + city: city, + country: country, + line1: line1, + line2: line2, + postalCode: postalCode, + state: state + ) + } +} + + +extension LocationStatus { + func toApi() -> LocationStatusApi? { + switch self { + case .unknown: + return nil + case .set: + return .set + case .notSet: + return .notSet + @unknown default: + fatalError("WTF") + } + } +} + +extension DeviceType { + func toApi() -> DeviceTypeApi { + switch self { + case .chipper2X: + return .chipper2X + case .verifoneP400: + return .verifoneP400 + case .wisePad3: + return .wisePad3 + case .stripeM2: + return .stripeM2 + case .wisePosE: + return .wisePosE + case .wisePosEDevKit: + return .wisePosEDevkit + case .etna: + return .etna + case .chipper1X: + return .chipper1X + case .wiseCube: + return .wiseCube + case .stripeS700: + return .stripeS700 + case .stripeS700DevKit: + return .stripeS700Devkit + case .appleBuiltIn: + return .appleBuiltIn + @unknown default: + fatalError("WTF") + } + } +} + +extension ReaderEvent { + func toApi() -> ReaderEventApi { + switch (self) { + case .cardInserted: + return .cardInserted + case .cardRemoved: + return .cardRemoved + @unknown default: + fatalError() + } + } +} + +extension ReaderDisplayMessage { + func toApi() -> ReaderDisplayMessageApi { + switch (self) { + case .retryCard: + return .retryCard + case .insertCard: + return .insertCard + case .insertOrSwipeCard: + return .insertOrSwipeCard + case .swipeCard: + return .swipeCard + case .removeCard: + return .removeCard + case .multipleContactlessCardsDetected: + return .multipleContactlessCardsDetected + case .tryAnotherReadMethod: + return .tryAnotherReadMethod + case .tryAnotherCard: + return .tryAnotherCard + case .cardRemovedTooEarly: + return .cardRemovedTooEarly + @unknown default: + fatalError() + } + } +} + +extension ReaderInputOptions { + func toApi() -> [ReaderInputOptionApi] { + var options: [ReaderInputOptionApi] = [] + if (contains(ReaderInputOptions.insertCard)) { options.append(ReaderInputOptionApi.insertCard) } + if (contains(ReaderInputOptions.swipeCard)) { options.append(ReaderInputOptionApi.swipeCard) } + if (contains(ReaderInputOptions.tapCard)) { options.append(ReaderInputOptionApi.tapCard) } + return options + } +} + +extension BatteryStatus { + func toApi() -> BatteryStatusApi? { + switch (self) { + case .critical: + return .critical + case .low: + return .low + case .nominal: + return .nominal + case .unknown: + return nil + @unknown default: + fatalError() + } + } +} + +extension ReaderSoftwareUpdate { + func toApi() -> ReaderSoftwareUpdateApi { + return ReaderSoftwareUpdateApi( + components: components.toApi(), + keyProfileName: nil, + onlyInstallRequiredUpdates: false, + requiredAt: requiredAt, + settingsVersion: nil, + timeEstimate: estimatedUpdateTime.toApi(), + version: deviceSoftwareVersion + ) + } +} + +extension UpdateComponent { + func toApi() -> [UpdateComponentApi] { + var components: [UpdateComponentApi] = [] + if (contains(UpdateComponent.incremental)) {components.append(UpdateComponentApi.incremental)} + if (contains(UpdateComponent.firmware)) {components.append(UpdateComponentApi.firmware)} + if (contains(UpdateComponent.config)) {components.append(UpdateComponentApi.config)} + if (contains(UpdateComponent.keys)) {components.append(UpdateComponentApi.keys)} + return components + } +} + +extension UpdateTimeEstimate { + func toApi() -> UpdateTimeEstimateApi { + switch self { + case .estimateLessThan1Minute: + return .lessThanOneMinute + case .estimate1To2Minutes: + return .oneToTwoMinutes + case .estimate2To5Minutes: + return .twoToFiveMinutes + case .estimate5To15Minutes: + return .fiveToFifteenMinutes + @unknown default: + fatalError("WTF") + } + } +} + +// PARAMS + +extension DiscoveryConfigurationApi { + func toHost() throws -> DiscoveryConfiguration? { + switch self { + case let config as BluetoothDiscoveryConfigurationApi: + return try BluetoothScanDiscoveryConfigurationBuilder() + .setTimeout(UInt(config.timeout ?? 0)) + .setSimulated(config.isSimulated) + .build() + case let config as BluetoothProximityDiscoveryConfigurationApi: + return try BluetoothProximityDiscoveryConfigurationBuilder() + .setSimulated(config.isSimulated) + .build() + case _ as HandoffDiscoveryConfigurationApi: + return nil + case let config as InternetDiscoveryConfigurationApi: + return try InternetDiscoveryConfigurationBuilder() + .setSimulated(config.isSimulated) + .setLocationId(config.locationId) + .build() + case let config as LocalMobileDiscoveryConfigurationApi: + return try LocalMobileDiscoveryConfigurationBuilder() + .setSimulated(config.isSimulated) + .build() + case _ as UsbDiscoveryConfigurationApi: + return nil + default: + fatalError() + } + } + + func toHostDiscoveryMethod() -> DiscoveryMethod? { + switch self { + case _ as BluetoothDiscoveryConfigurationApi: + return .bluetoothScan + case _ as BluetoothProximityDiscoveryConfigurationApi: + return .bluetoothProximity + case _ as HandoffDiscoveryConfigurationApi: + return nil + case _ as InternetDiscoveryConfigurationApi: + return .internet + case _ as LocalMobileDiscoveryConfigurationApi: + return .localMobile + case _ as UsbDiscoveryConfigurationApi: + return nil + default: + fatalError() + } + } + + func toHostSimulated() -> Bool { + switch self { + case let config as BluetoothDiscoveryConfigurationApi: + return config.isSimulated + case let config as BluetoothProximityDiscoveryConfigurationApi: + return config.isSimulated + case _ as HandoffDiscoveryConfigurationApi: + return false + case let config as InternetDiscoveryConfigurationApi: + return config.isSimulated + case let config as LocalMobileDiscoveryConfigurationApi: + return config.isSimulated + case _ as UsbDiscoveryConfigurationApi: + return false + default: + fatalError() + } + } +} + +extension DeviceTypeApi { + func toHost() -> DeviceType? { + switch self { + case .chipper2X: + return .chipper2X + case .verifoneP400: + return .verifoneP400 + case .wisePad3: + return .wisePad3 + case .stripeM2: + return .stripeM2 + case .wisePosE: + return .wisePosE + case .wisePosEDevkit: + return .wisePosEDevKit + case .etna: + return .etna + case .chipper1X: + return .chipper1X + case .wiseCube: + return .wiseCube + case .stripeS700: + return .stripeS700 + case .stripeS700Devkit: + return .stripeS700DevKit + case .appleBuiltIn: + return .appleBuiltIn + case .cotsDevice, .wisePad3s: + return nil + } + } +} + + +extension CartApi { + func toHost() throws -> Cart { + return try CartBuilder(currency: currency) + .setTax(tax) + .setTotal(total) + .setLineItems(lineItems.map { try $0.toHost()} ) + .build() + } +} + +extension CartLineItemApi { + func toHost() throws -> CartLineItem { + return try CartLineItemBuilder(displayName: description) + .setAmount(amount) + .setQuantity(quantity) + .build() + } +} + +// EXTRA + +extension ConnectionStatus { + func toApi() -> ConnectionStatusApi { + switch self { + case .notConnected: + return .notConnected + case .connected: + return .connected + case .connecting: + return .connecting + @unknown default: + fatalError("WTF") + } + } +} diff --git a/stripe_terminal/ios/Classes/Mappings/RefundMappings.swift b/stripe_terminal/ios/Classes/Mappings/RefundMappings.swift new file mode 100644 index 0000000..d446580 --- /dev/null +++ b/stripe_terminal/ios/Classes/Mappings/RefundMappings.swift @@ -0,0 +1,45 @@ +import Foundation +import StripeTerminal + +extension Refund { + func toApi() -> RefundApi { + return RefundApi( + id: stripeId, + amount: Int(amount), + chargeId: charge, + created: created, + currency: currency, + metadata: metadata, + reason: reason, + status: status.toApi(), + paymentMethodDetails: paymentMethodDetails?.toApi(), + failureReason: failureReason + ) + } +} + +extension RefundStatus { + func toApi() -> RefundStatusApi? { + switch self { + case .succeeded: + return .succeeded + case .pending: + return .pending + case .failed: + return .failed + case .unknown: + return nil + @unknown default: + fatalError() + } + } +} + +extension PaymentMethodDetails { + func toApi() -> PaymentMethodDetailsApi { + return PaymentMethodDetailsApi( + cardPresent: cardPresent?.toApi(), + interacPresent: interacPresent?.toApi() + ) + } +} diff --git a/stripe_terminal/ios/Classes/Mappings/SetupIntentMappings.swift b/stripe_terminal/ios/Classes/Mappings/SetupIntentMappings.swift new file mode 100644 index 0000000..67af37c --- /dev/null +++ b/stripe_terminal/ios/Classes/Mappings/SetupIntentMappings.swift @@ -0,0 +1,114 @@ +import Foundation +import StripeTerminal + +extension SetupIntent { + func toApi() -> SetupIntentApi { + return SetupIntentApi( + id : stripeId, + created: created, + customerId: customer, + metadata: metadata ?? [:], + usage: usage.toApi(), + status: status.toApi(), + latestAttempt: latestAttempt?.toApi() + ) + } +} + +extension SetupIntentUsage { + func toApi() -> SetupIntentUsageApi { + switch self { + case .offSession: + return .offSession + case .onSession: + return .onSession + @unknown default: + fatalError() + } + } +} + +extension SetupIntentStatus { + func toApi() -> SetupIntentStatusApi { + switch self { + case .requiresPaymentMethod: + return .requiresPaymentMethod + case .requiresConfirmation: + return .requiresConfirmation + case .requiresAction: + return .requiresAction + case .processing: + return .processing + case .canceled: + return .cancelled + case .succeeded: + return .succeeded + @unknown default: + fatalError() + } + } +} + +extension SetupAttempt { + func toApi() -> SetupAttemptApi { + let statusApi: SetupAttemptStatusApi + switch status { + case "requires_confirmation": + statusApi = .requiresConfirmation + case "requires_action": + statusApi = .requiresAction + case "processing": + statusApi = .processing + case "succeeded": + statusApi = .succeeded + case "failed": + statusApi = .failed + case "abandoned": + statusApi = .abandoned + default: + fatalError() + } + return SetupAttemptApi( + id : stripeId, + applicationId: application, + created: created, + customerId: customer, + onBehalfOf: onBehalfOf, + paymentMethodId: paymentMethod, + paymentMethodDetails: paymentMethodDetails?.toApi(), + setupIntentId: setupIntent, + status: statusApi + ) + } +} + +extension SetupAttemptPaymentMethodDetails { + func toApi() -> SetupAttemptPaymentMethodDetailsApi { + return SetupAttemptPaymentMethodDetailsApi( + cardPresent: cardPresent?.toApi(), + interacPresent: interacPresent?.toApi() + ) + } +} + +extension SetupAttemptCardPresentDetails { + func toApi() -> SetupAttemptCardPresentDetailsApi { + return SetupAttemptCardPresentDetailsApi( + emvAuthData: emvAuthData, + generatedCard: generatedCard + ) + } +} + +// PARAMS + +extension SetupIntentUsageApi { + func toHost() -> SetupIntentUsage { + switch self { + case .offSession: + return .offSession + case .onSession: + return .onSession + } + } +} diff --git a/stripe_terminal/ios/Classes/Mappings/TipMappings.swift b/stripe_terminal/ios/Classes/Mappings/TipMappings.swift index 9c47ed3..e12cf89 100644 --- a/stripe_terminal/ios/Classes/Mappings/TipMappings.swift +++ b/stripe_terminal/ios/Classes/Mappings/TipMappings.swift @@ -8,3 +8,13 @@ extension SCPTip { ) } } + +// PARAMS + +extension TippingConfigurationApi { + func toHost() throws -> TippingConfiguration { + return try TippingConfigurationBuilder() + .setEligibleAmount(eligibleAmount) + .build() + } +}