diff --git a/README.md b/README.md index 30e58e382..f91b5e93f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # ProcessOut Android SDK +Get started with the [documentation](https://docs.processout.com/docs/setting-up-your-environment#android-app-client) +or explore the [API reference](https://processout.github.io/processout-android/). + ## Requirements *Android 5.0 (API level 21) +* @@ -32,14 +35,6 @@ Prebuilt customizable UI to handle payment flows. implementation("com.processout:processout-android-ui:") ``` -## Documentation - -[ProcessOut Android SDK](sdk/documentation/ProcessOut.md)\ -[ProcessOut Android SDK - Checkout 3DS](checkout-3ds/documentation/ProcessOutCheckout3DS.md)\ -[ProcessOut Android SDK - UI](ui/documentation/ProcessOutUI.md)\ -\ -[API Reference](https://processout.github.io/processout-android/) - ## License ProcessOut is available under the MIT license. See the [LICENSE](LICENSE) file for more info. diff --git a/checkout-3ds/documentation/ProcessOutCheckout3DS.md b/checkout-3ds/documentation/ProcessOutCheckout3DS.md deleted file mode 100644 index bc9b37953..000000000 --- a/checkout-3ds/documentation/ProcessOutCheckout3DS.md +++ /dev/null @@ -1,81 +0,0 @@ -# Module ProcessOut Android SDK - Checkout 3DS - -## Overview - -Framework wraps Checkout SDK to make it easy to use with ProcessOut when making requests that may trigger 3DS2. - -## Integration - -SDK handles [deep link](https://developer.android.com/training/app-links#deep-links) to return back to your app after -authorization in the following format: `your.application.id://processout/return`\ -It is required to provide this deep link on the backend as `return_url` when creating invoice and as `invoice_return_url` -when creating token. - -### Implement 3DS service delegate - -```kotlin -// 1) Initialize launcher in Activity or Fragment. - -private lateinit var customTabLauncher: PO3DSRedirectCustomTabLauncher - -override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - customTabLauncher = PO3DSRedirectCustomTabLauncher.create(from = this) -} - -// 2) Implement POCheckout3DSServiceDelegate and pass launcher. - -class Checkout3DSServiceDelegate( - private val activity: Activity, - private val customTabLauncher: PO3DSRedirectCustomTabLauncher -) : POCheckout3DSServiceDelegate { - - override fun configuration(parameters: ConfigParameters): ThreeDS2ServiceConfiguration { - return ThreeDS2ServiceConfiguration( - context = activity, - configParameters = parameters, - // Optional properties. - locale = Locale.UK, - uiCustomization = UICustomization(), - appUri = Uri.parse("https://my-app-url.com"), - challengeTimeout = 300 - ) - } - - override fun shouldContinue(warnings: Set, callback: (Boolean) -> Unit) { - // Default implementation ignores all warnings. - // As an example we can define to continue the flow - // only if there is no warnings or all warnings have low severity. - callback(warnings.all { it.severity == Severity.LOW }) - } - - override fun handle(redirect: PO3DSRedirect, callback: (ProcessOutResult) -> Unit) { - customTabLauncher.launch( - redirect = redirect, - returnUrl = "your.application.id://processout/return", - callback = callback - ) - } - - // 3) Optionally implement service lifecycle callbacks for logs or custom logic. - - override fun willCreateAuthenticationRequest(configuration: PO3DS2Configuration) {} - - override fun didCreateAuthenticationRequest(result: ProcessOutResult) {} - - override fun willHandle(challenge: PO3DS2Challenge) {} - - override fun didHandle3DS2Challenge(result: ProcessOutResult) {} -} -``` - -### Create 3DS service - -```kotlin -val threeDSService = POCheckout3DSService.Builder( - activity = this, - delegate = Checkout3DSServiceDelegate(activity = this, customTabLauncher) -) // Optional parameter, by default Environment.PRODUCTION - .with(environment = Environment.SANDBOX) - .build() -``` diff --git a/sdk/documentation/3DS.md b/sdk/documentation/3DS.md deleted file mode 100644 index ce81fd46b..000000000 --- a/sdk/documentation/3DS.md +++ /dev/null @@ -1,79 +0,0 @@ -# Module ProcessOut Android SDK - -## Getting Started With 3DS - -Some SDK methods may trigger 3DS flow, those methods could be identified by presence of required -parameter `threeDSService: PO3DSService`. For example: - -```kotlin -fun authorizeInvoice( - request: POInvoiceAuthorizationRequest, - threeDSService: PO3DSService -) -``` - -### 3DS2 - -Most PSPs have their own certified SDKs for 3DS2 in mobile apps but they all have equivalent features. -`PO3DSService` allows to abstract the details of 3DS handling and supply functionality in a consistent way. - -We have our own implementation `POTest3DSService` that emulates the normal 3DS authentication flow -but does not actually make any calls to a real Access Control Server (ACS). -It is mainly useful during development in our sandbox testing environment. -Usage example: - -```kotlin -fun authorizeInvoice(invoiceId: String, cardId: String) { - ProcessOut.instance.invoices.authorizeInvoice( - request = POInvoiceAuthorizationRequest( - invoiceId = invoiceId, - source = cardId - ), - threeDSService = POTest3DSService(activity = this, customTabLauncher = null) - ) -} - -// Subscribe to collect result in coroutines scope before calling method. -ProcessOut.instance.invoices.authorizeInvoiceResult - .collect { result -> - // handle result - } -``` - -### 3DS Redirect with Custom Chrome Tabs (since 4.7.0) - -To handle web based redirects service must implement method:\ -`PO3DSService.handle(redirect: PO3DSRedirect, callback: (ProcessOutResult) -> Unit)` - -`PO3DSRedirectCustomTabLauncher` allows to automatically redirect user to provided URL and collect the result. -Launcher will open Custom Tab ([overview](https://developer.chrome.com/docs/android/custom-tabs/)) when Chrome -is installed and enabled on the device even if it's not a default browser, -otherwise it will automatically fallback to the WebView. - -SDK handles [deep link](https://developer.android.com/training/app-links#deep-links) to return back to your app after -authorization in the following format: `your.application.id://processout/return`\ -It is required to provide this deep link on the backend as `return_url` when creating invoice and as `invoice_return_url` -when creating token. - -Integration steps: - -```kotlin -// 1) Initialize launcher in Activity or Fragment. - -private lateinit var customTabLauncher: PO3DSRedirectCustomTabLauncher - -override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - customTabLauncher = PO3DSRedirectCustomTabLauncher.create(from = this) -} - -// 2) Pass launcher to implementation of PO3DSService or POTest3DSService and handle redirect. - -override fun handle(redirect: PO3DSRedirect, callback: (ProcessOutResult) -> Unit) { - customTabLauncher.launch( - redirect = redirect, - returnUrl = "your.application.id://processout/return", - callback = callback - ) -} -``` diff --git a/sdk/documentation/AlternativePaymentMethods.md b/sdk/documentation/AlternativePaymentMethods.md deleted file mode 100644 index e0005321a..000000000 --- a/sdk/documentation/AlternativePaymentMethods.md +++ /dev/null @@ -1,51 +0,0 @@ -# Module ProcessOut Android SDK - -## Alternative Payment Methods - -`POAlternativePaymentMethodCustomTabLauncher` allows to handle Alternative Payment Methods by provided request parameters -or URL and collect the result. -Launcher will open Custom Tab ([overview](https://developer.chrome.com/docs/android/custom-tabs/)) when Chrome -is installed and enabled on the device even if it's not a default browser, -otherwise it will automatically fallback to the WebView. - -SDK handles [deep link](https://developer.android.com/training/app-links#deep-links) to return back to your app after -authorization in the following format: `your.application.id://processout/return`\ -It is required to provide this deep link on the backend as `return_url` when creating invoice and as `invoice_return_url` -when creating token. - -Integration steps: - -```kotlin -// 1) It is required to initialize launcher in onCreate() method of Activity or Fragment. - -private lateinit var customTabLauncher: POAlternativePaymentMethodCustomTabLauncher - -override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - customTabLauncher = POAlternativePaymentMethodCustomTabLauncher.create(from = this) { result -> - when (result) { - is ProcessOutResult.Success -> TODO() - is ProcessOutResult.Failure -> TODO() - } - } -} - -// 2) Launch the activity. - -// Launch activity with URL created from request. -customTabLauncher.launch( - request = POAlternativePaymentMethodRequest( - invoiceId = "iv_", - gatewayConfigurationId = "gway_conf_", - customerId = "cust_", - tokenId = "tok_" - ), - returnUrl = "your.application.id://processout/return" -) - -// Launch activity with custom URL. -customTabLauncher.launch( - uri = Uri.parse("https://your_custom_url"), - returnUrl = "your.application.id://processout/return" -) -``` diff --git a/sdk/documentation/ApiExamples.md b/sdk/documentation/ApiExamples.md deleted file mode 100644 index 9fe9a8cd8..000000000 --- a/sdk/documentation/ApiExamples.md +++ /dev/null @@ -1,43 +0,0 @@ -# Module ProcessOut Android SDK - -## API Usage Examples - -### List available native APMs - -```kotlin -// Coroutine function - -val request = POAllGatewayConfigurationsRequest( - filter = POAllGatewayConfigurationsRequest.Filter.NATIVE_ALTERNATIVE_PAYMENT_METHODS, - withDisabled = false -) -val result = ProcessOut.instance.gatewayConfigurations.fetch(request) -when (result) { - is ProcessOutResult.Success -> TODO() - is ProcessOutResult.Failure -> TODO() -} - -// Callback function - -val request = POAllGatewayConfigurationsRequest( - filter = POAllGatewayConfigurationsRequest.Filter.NATIVE_ALTERNATIVE_PAYMENT_METHODS, - withDisabled = false -) -ProcessOut.instance.gatewayConfigurations.fetch( - request = request, - callback = object : ProcessOutCallback { - override fun onSuccess(result: POAllGatewayConfigurations) { - TODO() - } - - override fun onFailure( - code: POFailure.Code, - message: String?, - invalidFields: List?, - cause: Exception? - ) { - TODO() - } - } -) -``` diff --git a/sdk/documentation/ErrorHandling.md b/sdk/documentation/ErrorHandling.md deleted file mode 100644 index 55cac2b81..000000000 --- a/sdk/documentation/ErrorHandling.md +++ /dev/null @@ -1,35 +0,0 @@ -# Module ProcessOut Android SDK - -## Error Handling - -Occurred errors are provided -as [ProcessOutResult.Failure](https://processout.github.io/processout-android/sdk/com.processout.sdk.core/-process-out-result/-failure/index.html) -with [POFailure](https://processout.github.io/processout-android/sdk/com.processout.sdk.core/-p-o-failure/index.html) -error code and details. - -```kotlin -when (result) { - is ProcessOutResult.Success -> TODO() - is ProcessOutResult.Failure -> { - // Raw error code value is the same on Android and iOS for the same error code. - val rawErrorCodeValue: String = result.code.rawValue - - // Handle specific failure types. - when (val code = result.code) { - is POFailure.Code.Authentication -> code.authenticationCode // TODO() - is POFailure.Code.Validation -> code.validationCode // TODO() - is POFailure.Code.NotFound -> code.notFoundCode // TODO() - is POFailure.Code.Timeout -> - when (code.timeoutCode) { - POFailure.TimeoutCode.mobile -> TODO() - POFailure.TimeoutCode.gateway -> TODO() - } - POFailure.Code.NetworkUnreachable -> TODO() - POFailure.Code.Cancelled -> TODO() - is POFailure.Code.Generic -> code.genericCode // TODO() - is POFailure.Code.Internal -> code.internalCode // TODO() - is POFailure.Code.Unknown -> code.rawValue // TODO() - } - } -} -``` diff --git a/sdk/documentation/Initialization.md b/sdk/documentation/Initialization.md deleted file mode 100644 index c94d31921..000000000 --- a/sdk/documentation/Initialization.md +++ /dev/null @@ -1,25 +0,0 @@ -# Module ProcessOut Android SDK - -## Initialization - -```kotlin -import com.processout.sdk.api.ProcessOut -import com.processout.sdk.api.ProcessOutConfiguration - -ProcessOut.configure( - ProcessOutConfiguration( - application = this, - projectId = "your_project_id", - debug = true // Optionally enable debug mode for logs - ) -) -``` - -### Access initialized singleton instances - -```kotlin -ProcessOut.instance - -// Legacy deprecated ProcessOut -ProcessOut.legacyInstance -``` diff --git a/sdk/documentation/MigrationFrom3To4.md b/sdk/documentation/MigrationFrom3To4.md deleted file mode 100644 index c12189bf1..000000000 --- a/sdk/documentation/MigrationFrom3To4.md +++ /dev/null @@ -1,22 +0,0 @@ -# Module ProcessOut Android SDK - -## Migration From v3 To v4 - -### Breaking changes - -- `ProcessOutApi` -> `ProcessOut`\ - `ProcessOutApiConfiguration` -> `ProcessOutConfiguration` -- `GatewayConfigurationsRepository` -> `POGatewayConfigurationsRepository`\ - `CardsRepository` -> `POCardsRepository`\ - `InvoicesRepository` -> `POInvoicesService`\ - `CustomerTokensRepository` -> `POCustomerTokensService`\ - `AlternativePaymentMethodProvider` -> `POAlternativePaymentMethodsService`\ - `NativeAlternativePaymentMethodEventDispatcher` -> `PONativeAlternativePaymentMethodEventDispatcher` -- `PONativeAlternativePaymentMethodParameter.ParameterType` enum values has been renamed and extended. - -```kotlin -// Native APM parameter type: -val parameter: PONativeAlternativePaymentMethodParameter -val type = parameter.type() -val rawType = parameter.rawType -``` diff --git a/sdk/documentation/NativeAlternativePaymentMethods.md b/sdk/documentation/NativeAlternativePaymentMethods.md deleted file mode 100644 index 1d067a1f9..000000000 --- a/sdk/documentation/NativeAlternativePaymentMethods.md +++ /dev/null @@ -1,163 +0,0 @@ -# Module ProcessOut Android SDK - -## Native Alternative Payment Methods - -### Launch native APM payment sheet - -```kotlin -// 1) It is required to initialize launcher in onCreate() method of Activity or Fragment. - -private lateinit var launcher: PONativeAlternativePaymentMethodLauncher - -override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - launcher = PONativeAlternativePaymentMethodLauncher.create(from = this) { result -> - when (result) { - PONativeAlternativePaymentMethodResult.Success -> TODO() - is PONativeAlternativePaymentMethodResult.Failure -> TODO() - } - } -} - -// 2) Launch the activity. - -launcher.launch( - PONativeAlternativePaymentMethodConfiguration( - gatewayConfigurationId = "gway_conf_", - invoiceId = "iv_" - ) -) -``` - -### Customization of the payment sheet - -```kotlin -val payButtonStyle = POButtonStyle( - normal = POButtonStateStyle( - text = POTextStyle(Color.WHITE, POTypography.actionDefaultMedium), - border = POBorderStyle(radiusDp = 16, widthDp = 0, color = Color.TRANSPARENT), - backgroundColor = Color.parseColor("#ffff8800"), - elevationDp = 2, - paddingDp = POButtonStateStyle.DEFAULT_PADDING - ), - disabled = POButtonStateStyle( - text = POTextStyle(Color.GRAY, POTypography.actionDefaultMedium), - border = POBorderStyle(radiusDp = 16, widthDp = 0, color = Color.TRANSPARENT), - backgroundColor = Color.LTGRAY, - elevationDp = 0, - paddingDp = POButtonStateStyle.DEFAULT_PADDING - ), - highlighted = POButtonHighlightedStyle( - textColor = Color.WHITE, - borderColor = Color.TRANSPARENT, - backgroundColor = Color.parseColor("#ffffbb33") - ), - progressIndicatorColor = Color.WHITE -) - -launcher.launch( - PONativeAlternativePaymentMethodConfiguration( - gatewayConfigurationId = "gway_conf_", - invoiceId = "iv_", - style = Style( - primaryButton = payButtonStyle - ), - options = Options( - title = "Payment details", - primaryActionText = "Submit", - secondaryAction = SecondaryAction.Cancel("Go Back"), - cancellation = Cancellation( - dragDown = true, - touchOutside = false, - backPressed = false - ), - successMessage = "Payment confirmed.\nThank you!", - skipSuccessScreen = true, // Only applies when 'waitsPaymentConfirmation = true' - waitsPaymentConfirmation = true, - paymentConfirmationTimeoutSeconds = Options.MAX_PAYMENT_CONFIRMATION_TIMEOUT_SECONDS, - paymentConfirmationSecondaryAction = SecondaryAction.Cancel( - text = "Cancel", - disabledForSeconds = 30 - ) - ) - ) -) -``` - -### Payment sheet error handling - -```kotlin -when (result) { - PONativeAlternativePaymentMethodResult.Success -> TODO() - is PONativeAlternativePaymentMethodResult.Failure -> { - // Raw error code value is the same on Android and iOS for the same error code. - val rawErrorCodeValue: String = result.code.rawValue - - // Handle specific failure types. - when (val code = result.code) { - is POFailure.Code.Authentication -> code.authenticationCode // TODO() - is POFailure.Code.Validation -> code.validationCode // TODO() - is POFailure.Code.NotFound -> code.notFoundCode // TODO() - is POFailure.Code.Timeout -> code.timeoutCode // TODO() - POFailure.Code.NetworkUnreachable -> TODO() - POFailure.Code.Cancelled -> TODO() - is POFailure.Code.Generic -> code.genericCode // TODO() - is POFailure.Code.Internal -> code.internalCode // TODO() - is POFailure.Code.Unknown -> code.rawValue // TODO() - } - } -} -``` - -### Subscribe to payment sheet lifecycle events - -```kotlin -viewModelScope.launch { - ProcessOut.instance.dispatchers.nativeAlternativePaymentMethod - .events.collect { event -> - when (event) { - PONativeAlternativePaymentMethodEvent.WillStart -> TODO() - PONativeAlternativePaymentMethodEvent.DidStart -> TODO() - PONativeAlternativePaymentMethodEvent.ParametersChanged -> TODO() - PONativeAlternativePaymentMethodEvent.WillSubmitParameters -> TODO() - is PONativeAlternativePaymentMethodEvent.DidSubmitParameters -> TODO() - is PONativeAlternativePaymentMethodEvent.DidFailToSubmitParameters -> TODO() - is PONativeAlternativePaymentMethodEvent.WillWaitForCaptureConfirmation -> TODO() - PONativeAlternativePaymentMethodEvent.DidRequestCancelConfirmation -> TODO() - PONativeAlternativePaymentMethodEvent.DidCompletePayment -> TODO() - is PONativeAlternativePaymentMethodEvent.DidFail -> TODO() - } - } -} -``` - -### Provide default values for payment sheet input fields - -```kotlin -viewModelScope.launch { - with(ProcessOut.instance.dispatchers.nativeAlternativePaymentMethod) { - // Subscribe for request to provide default values. - defaultValuesRequest.collect { request -> - // Default values should be provided as Map - // where key is PONativeAlternativePaymentMethodParameter.key - // and value is a custom default value. - val defaultValues = mutableMapOf() - - // Populate default values map based on request parameters. - // It's not mandatory to provide defaults for all parameters. - request.parameters.find { - it.type() == ParameterType.PHONE - }?.also { - defaultValues[it.key] = "+111122223333" - } - - // Provide response which must be constructed from request with default values payload. - // Note that once you've subscribed to 'defaultValuesRequest' - // it's required to send response back, otherwise the payment flow will not proceed. - // If there is no default values to provide it's still required - // to call this method with 'emptyMap()'. - provideDefaultValues(request.toResponse(defaultValues)) - } - } -} -``` diff --git a/sdk/documentation/ProcessOut.md b/sdk/documentation/ProcessOut.md deleted file mode 100644 index f7239a004..000000000 --- a/sdk/documentation/ProcessOut.md +++ /dev/null @@ -1,17 +0,0 @@ -# Module ProcessOut Android SDK - -### [Initialization](Initialization.md) - -### [Services & Launchers](Services.md) - -### [API Usage Examples](ApiExamples.md) - -### [Error Handling](ErrorHandling.md) - -### [Getting Started With 3DS](3DS.md) - -### [Alternative Payment Methods](AlternativePaymentMethods.md) - -### [Native Alternative Payment Methods](NativeAlternativePaymentMethods.md) - -### [Migration From v3 To v4](MigrationFrom3To4.md) diff --git a/sdk/documentation/Services.md b/sdk/documentation/Services.md deleted file mode 100644 index 0988fdc82..000000000 --- a/sdk/documentation/Services.md +++ /dev/null @@ -1,19 +0,0 @@ -# Module ProcessOut Android SDK - -## Services - -[POGatewayConfigurationsRepository](https://processout.github.io/processout-android/sdk/com.processout.sdk.api.repository/-p-o-gateway-configurations-repository/index.html)\ -[POCardsRepository](https://processout.github.io/processout-android/sdk/com.processout.sdk.api.repository/-p-o-cards-repository/index.html)\ -[POInvoicesService](https://processout.github.io/processout-android/sdk/com.processout.sdk.api.service/-p-o-invoices-service/index.html)\ -[POCustomerTokensService](https://processout.github.io/processout-android/sdk/com.processout.sdk.api.service/-p-o-customer-tokens-service/index.html)\ -[POAlternativePaymentMethodsService](https://processout.github.io/processout-android/sdk/com.processout.sdk.api.service/-p-o-alternative-payment-methods-service/index.html)\ -[PONativeAlternativePaymentMethodEventDispatcher](https://processout.github.io/processout-android/sdk/com.processout.sdk.api.dispatcher/-p-o-native-alternative-payment-method-event-dispatcher/index.html)\ -[POBrowserCapabilitiesService](https://processout.github.io/processout-android/sdk/com.processout.sdk.api.service/-p-o-browser-capabilities-service/index.html)\ -[PO3DSService](https://processout.github.io/processout-android/sdk/com.processout.sdk.api.service/-p-o3-d-s-service/index.html)\ -[POTest3DSService](https://processout.github.io/processout-android/sdk/com.processout.sdk.ui.threeds/-p-o-test3-d-s-service/index.html) - -### Launchers - -[PO3DSRedirectCustomTabLauncher](https://processout.github.io/processout-android/sdk/com.processout.sdk.ui.threeds/-p-o3-d-s-redirect-custom-tab-launcher/index.html)\ -[POAlternativePaymentMethodCustomTabLauncher](https://processout.github.io/processout-android/sdk/com.processout.sdk.ui.apm/-p-o-alternative-payment-method-custom-tab-launcher/index.html)\ -[PONativeAlternativePaymentMethodLauncher](https://processout.github.io/processout-android/sdk/com.processout.sdk.ui.nativeapm/-p-o-native-alternative-payment-method-launcher/index.html) diff --git a/ui/documentation/CardTokenization.md b/ui/documentation/CardTokenization.md deleted file mode 100644 index 5f29b4817..000000000 --- a/ui/documentation/CardTokenization.md +++ /dev/null @@ -1,138 +0,0 @@ -# Module ProcessOut Android SDK - UI - -## Card Tokenization (since 4.15.0) - -### Launch Card Tokenization Bottom Sheet - -```kotlin -// 1) It is required to initialize launcher in onCreate() method of Activity or Fragment. - -private lateinit var launcher: POCardTokenizationLauncher - -override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - launcher = POCardTokenizationLauncher.create(from = this) { result -> - result.onSuccess { card -> - TODO() - }.onFailure { TODO() } - } -} - -// 2) Launch the activity. - -launcher.launch(POCardTokenizationConfiguration()) -``` - -### Configuration - -```kotlin -POCardTokenizationConfiguration( - title = "Add New Card", - isCardholderNameFieldVisible = true, - billingAddress = POCardTokenizationConfiguration.BillingAddressConfiguration( - // Configure how to collect the billing address. - ), - primaryActionText = "Submit", - secondaryActionText = "Cancel", - cancellation = POCancellationConfiguration( - secondaryAction = true, - backPressed = false, - dragDown = true, - touchOutside = false - ), - metadata = null, // Metadata related to the card. - style = POCardTokenizationConfiguration.Style( - // Customize the look and feel. - ) -) -``` - -### Error Handling - -```kotlin -viewModelScope.launch { - with(ProcessOut.instance.dispatchers.cardTokenization) { - shouldContinueRequest.collect { request -> - // Inspect the failure to decide whether the flow should continue or complete. - val shouldContinue = when (val code = request.failure.code) { - is Generic -> when (code.genericCode) { - requestInvalidCard, - cardInvalid -> false - else -> true - } - else -> false - } - // Notify by sending the response which must be constructed from request. - // Note that once you've subscribed to 'shouldContinueRequest' - // it's required to send response back otherwise the card tokenization flow will not proceed. - shouldContinue(request.toResponse(shouldContinue = shouldContinue)) - } - } -} -``` - -### Lifecycle Events - -```kotlin -viewModelScope.launch { - ProcessOut.instance.dispatchers.cardTokenization - .events.collect { event -> - when (event) { - WillStart -> TODO() - DidStart -> TODO() - ParametersChanged -> TODO() - WillTokenize -> TODO() - is DidTokenize -> event.card // TODO() - DidComplete -> TODO() - } - } -} -``` - -### Provide Preferred Scheme - -```kotlin -viewModelScope.launch { - with(ProcessOut.instance.dispatchers.cardTokenization) { - preferredSchemeRequest.collect { request -> - // Inspect issuer information to choose a default preferred scheme. - val preferredScheme = when (request.issuerInformation.scheme) { - "visa", "mastercard" -> request.issuerInformation.coScheme - else -> request.issuerInformation.scheme - } - // Send the response with preferred scheme which must be constructed from request. - // Note that once you've subscribed to 'preferredSchemeRequest' it's required to send response back. - // Implementation will use primary scheme if 'preferredScheme' is null. - preferredScheme(request.toResponse(preferredScheme = preferredScheme)) - } - } -} -``` - -### Process Tokenized Card - -```kotlin -// 1) Subscribe to additionally process tokenized card before completion (e.g. authorize invoice or assign customer token). - -lifecycleScope.launch { - ProcessOut.instance.dispatchers.cardTokenization - .processTokenizedCardRequest.collect { request -> - ProcessOut.instance.invoices.authorizeInvoice( - request = POInvoiceAuthorizationRequest( - invoiceId = "iv_", - source = request.card.id - ), - threeDSService = create3DSService() - ) - } -} - -// 2) Once you've subscribed it's required to call [complete] after processing. - -lifecycleScope.launch { - ProcessOut.instance.invoices - .authorizeInvoiceResult.collect { result -> - ProcessOut.instance.dispatchers.cardTokenization.complete(result) - } -} -``` diff --git a/ui/documentation/CardUpdate.md b/ui/documentation/CardUpdate.md deleted file mode 100644 index 4e142b536..000000000 --- a/ui/documentation/CardUpdate.md +++ /dev/null @@ -1,103 +0,0 @@ -# Module ProcessOut Android SDK - UI - -## Card Update (since 4.10.0) - -### Launch Card Update Bottom Sheet - -```kotlin -// 1) It is required to initialize launcher in onCreate() method of Activity or Fragment. - -private lateinit var launcher: POCardUpdateLauncher - -override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - launcher = POCardUpdateLauncher.create(from = this) { result -> - result.onSuccess { card -> - TODO() - }.onFailure { TODO() } - } -} - -// 2) Launch the activity. - -launcher.launch( - POCardUpdateConfiguration( - cardId = "card_" - ) -) -``` - -### Configuration - -```kotlin -POCardUpdateConfiguration( - cardId = "card_", - options = POCardUpdateConfiguration.Options( - title = "Payment Details", - cardInformation = POCardUpdateConfiguration.CardInformation( - maskedNumber = "4010 **** **** **21", - iin = "401000", - scheme = "visa", - preferredScheme = "carte bancaire" - ), - primaryActionText = "Submit", - secondaryActionText = "Cancel", - cancellation = POCancellationConfiguration( - secondaryAction = true, - backPressed = false, - dragDown = true, - touchOutside = false - ) - ), - style = POCardUpdateConfiguration.Style( - // Customize the look and feel. - ) -) -``` - -### Error Handling - -```kotlin -viewModelScope.launch { - with(ProcessOut.instance.dispatchers.cardUpdate) { - shouldContinueRequest.collect { request -> - // Inspect the failure to decide whether the flow should continue or complete. - val shouldContinue = when (val code = request.failure.code) { - is Generic -> when (code.genericCode) { - requestInvalidCard, - cardInvalid, - cardBadTrackData, - cardMissingCvc, - cardInvalidCvc, - cardFailedCvc, - cardFailedCvcAndAvs -> true - else -> false - } - else -> false - } - - // Notify by sending the response which must be constructed from request. - // Note that once you've subscribed to 'shouldContinueRequest' - // it's required to send response back otherwise the card update flow will not proceed. - shouldContinue(request.toResponse(shouldContinue = shouldContinue)) - } - } -} - -``` - -### Lifecycle Events - -```kotlin -viewModelScope.launch { - ProcessOut.instance.dispatchers.cardUpdate - .events.collect { event -> - when (event) { - POCardUpdateEvent.DidStart -> TODO() - POCardUpdateEvent.ParametersChanged -> TODO() - POCardUpdateEvent.WillUpdateCard -> TODO() - POCardUpdateEvent.DidComplete -> TODO() - } - } -} -``` diff --git a/ui/documentation/GooglePayCardTokenization.md b/ui/documentation/GooglePayCardTokenization.md deleted file mode 100644 index fe7155319..000000000 --- a/ui/documentation/GooglePayCardTokenization.md +++ /dev/null @@ -1,54 +0,0 @@ -# Module ProcessOut Android SDK - UI - -## Google Pay Card Tokenization (since 4.16.0) - -### Overview - -ProcessOut integration with Google Pay API for card tokenization. -Please also check our [documentation](https://docs.processout.com/docs/using-google-pay) -and [Google's overview](https://developers.google.com/pay/api/android/overview) -for initial configuration. - -### Launch Google Pay Payment Sheet - -```kotlin -// 1) It is required to initialize launcher in onCreate() method of Activity or Fragment. - -private lateinit var launcher: POGooglePayCardTokenizationLauncher - -override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - launcher = POGooglePayCardTokenizationLauncher.create( - from = this, - walletOptions = WalletOptions.Builder() - .setEnvironment(WalletConstants.ENVIRONMENT_TEST) - .build() - ) { result -> - result.onSuccess { data -> - // Get a ProcessOut card token created from a Google Pay token. - // It can be used to authorize an invoice or assign a customer token. - data.card.id - }.onFailure { TODO() } - } -} - -// 2) Check API readiness and setup a Google Pay button to launch the payment sheet. -// Note that GooglePayConfiguration is only an example and does not exist. -// You need to provide your own configuration and requests by following Google's tutorial. - -lifecycleScope.launch { - if (!launcher.isReadyToPay(GooglePayConfiguration.isReadyToPayRequest())) { - return@launch - } - with(binding.googlePayButton) { - val options = ButtonOptions.newBuilder() - .setAllowedPaymentMethods(GooglePayConfiguration.allowedPaymentMethods.toString()) - .build() - initialize(options) - setOnClickListener { - val paymentDataRequestJson = GooglePayConfiguration.getPaymentDataRequest(priceCents = 100L) - launcher.launch(paymentDataRequestJson) - } - } -} -``` diff --git a/ui/documentation/NativeAlternativePaymentMethods.md b/ui/documentation/NativeAlternativePaymentMethods.md deleted file mode 100644 index adca49873..000000000 --- a/ui/documentation/NativeAlternativePaymentMethods.md +++ /dev/null @@ -1,154 +0,0 @@ -# Module ProcessOut Android SDK - UI - -## Native Alternative Payment Methods (Compose) (since 4.19.0) - -### Launch Payment Sheet - -```kotlin -// 1) Initialize the launcher in the onCreate() method of Activity or Fragment. - -import com.processout.sdk.ui.napm.PONativeAlternativePaymentConfiguration -import com.processout.sdk.ui.napm.PONativeAlternativePaymentLauncher - -private lateinit var launcher: PONativeAlternativePaymentLauncher - -override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - launcher = PONativeAlternativePaymentLauncher.create(from = this) { result -> - result.onSuccess { - // Handle success. - }.onFailure { failure -> - // Handle failure. - } - } -} - -// 2) Launch the activity. - -launcher.launch( - PONativeAlternativePaymentConfiguration( - invoiceId = "iv_", - gatewayConfigurationId = "gway_conf_" - ) -) -``` - -### Configuration & Customization - -```kotlin -import com.processout.sdk.ui.napm.PONativeAlternativePaymentConfiguration -import com.processout.sdk.ui.napm.PONativeAlternativePaymentConfiguration.* - -launcher.launch( - PONativeAlternativePaymentConfiguration( - invoiceId = "iv_", - gatewayConfigurationId = "gway_conf_", - options = Options( - title = "Payment Details", - primaryActionText = "Submit", - secondaryAction = SecondaryAction.Cancel(text = "Cancel"), - cancellation = CancellationConfiguration( - backPressed = false, - dragDown = true, - touchOutside = false - ), - paymentConfirmation = PaymentConfirmationConfiguration( - waitsConfirmation = true, - timeoutSeconds = PaymentConfirmationConfiguration.MAX_TIMEOUT_SECONDS, - showProgressIndicatorAfterSeconds = 10, - secondaryAction = SecondaryAction.Cancel( - text = "Cancel", - disabledForSeconds = 10, - confirmation = POActionConfirmationConfiguration( - title = "Cancel payment?", - message = "Your payment will be cancelled.", - confirmActionText = "Cancel payment", - dismissActionText = "Not now" - ) - ) - ), - inlineSingleSelectValuesLimit = 5, - skipSuccessScreen = true, - successMessage = null - ), - style = Style( - // Customize the look and feel. - ) - ) -) -``` - -### Error Handling - -```kotlin -result.onFailure { failure -> - // Raw error code value is the same on Android and iOS for the same error code. - val rawErrorCodeValue: String = failure.code.rawValue - - // Handle specific failure types. - when (val code = failure.code) { - Cancelled -> TODO() - NetworkUnreachable -> TODO() - is Timeout -> code.timeoutCode // TODO() - is Generic -> code.genericCode // TODO() - is Authentication -> code.authenticationCode // TODO() - is Validation -> code.validationCode // TODO() - is NotFound -> code.notFoundCode // TODO() - is Internal -> code.internalCode // TODO() - is Unknown -> code.rawValue // TODO() - } -} -``` - -### Lifecycle Events - -```kotlin -viewModelScope.launch { - ProcessOut.instance.dispatchers.nativeAlternativePaymentMethod - .events.collect { event -> - when (event) { - WillStart -> TODO() - DidStart -> TODO() - ParametersChanged -> TODO() - WillSubmitParameters -> TODO() - is DidSubmitParameters -> TODO() - is DidFailToSubmitParameters -> TODO() - is WillWaitForCaptureConfirmation -> TODO() - DidRequestCancelConfirmation -> TODO() - DidCompletePayment -> TODO() - is DidFail -> TODO() - } - } -} -``` - -### Provide Default Values - -```kotlin -viewModelScope.launch { - with(ProcessOut.instance.dispatchers.nativeAlternativePaymentMethod) { - // Subscribe for request to provide default values. - defaultValuesRequest.collect { request -> - // Default values should be provided as Map - // where key is PONativeAlternativePaymentMethodParameter.key - // and value is a custom default value. - val defaultValues = mutableMapOf() - - // Populate default values map based on request parameters. - // It's not mandatory to provide defaults for all parameters. - request.parameters.find { - it.type() == ParameterType.PHONE - }?.also { - defaultValues[it.key] = "+111122223333" - } - - // Provide response which must be constructed from request with default values payload. - // Note that once you've subscribed to 'defaultValuesRequest' - // it's required to send response back, otherwise the payment flow will not proceed. - // If there is no default values to provide it's still required - // to call this method with 'emptyMap()'. - provideDefaultValues(request.toResponse(defaultValues)) - } - } -} -``` diff --git a/ui/documentation/ProcessOutUI.md b/ui/documentation/ProcessOutUI.md deleted file mode 100644 index bebfe050a..000000000 --- a/ui/documentation/ProcessOutUI.md +++ /dev/null @@ -1,9 +0,0 @@ -# Module ProcessOut Android SDK - UI - -### [Card Tokenization](CardTokenization.md) - -### [Google Pay Card Tokenization](GooglePayCardTokenization.md) - -### [Card Update](CardUpdate.md) - -### [Native Alternative Payment Methods](NativeAlternativePaymentMethods.md)