Skip to content

Feature/pimob 4287 add subdomain prefix#302

Draft
zane-smith-cko wants to merge 6 commits intomasterfrom
feature/PIMOB-4287_add_subdomain_prefix
Draft

Feature/pimob 4287 add subdomain prefix#302
zane-smith-cko wants to merge 6 commits intomasterfrom
feature/PIMOB-4287_add_subdomain_prefix

Conversation

@zane-smith-cko
Copy link

Issue

Issue ticket number and link.

Proposed changes

Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. If it fixes a bug or resolves a feature request, be sure to link to that issue.

Test Steps

If there's any functionality change, please list a step by step guide of how to verify the changes, and/or upload a screen recording for any visible changes.

For instance:

  1. Go to the main screen
  2. Tap on primary button
  3. Verify the image is shown on the screen

Checklist

Put an x in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.

  • Reviewers assigned
  • I have performed a self-review of my code and manual testing
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if applicable)

Further comments

If this is a relatively large or complex change, kick off the discussion by explaining why you choose the solution you did and what alternatives you considered, etc...

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for an optional subdomain/base-URL prefix so tokenization requests can be routed via a regional/merchant-specific subdomain, and wires this through Frames + CVV flows with updated samples and tests.

Changes:

  • Introduces baseUrlPrefix in Frames configuration/DI and propagates it down to CheckoutApiServiceFactory.
  • Adds Environment.toBaseUrl(...) URL building with prefix validation and corresponding unit tests.
  • Updates example apps and unit tests to pass the new prefix argument(s).

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
frames/src/test/java/com/checkout/frames/screen/paymentform/PaymentFormViewModelTest.kt Updates test setup to include baseUrlPrefix when constructing the VM factory.
frames/src/test/java/com/checkout/frames/screen/paymentform/PaymentFormConfigTest.kt Extends config test coverage to include baseUrlPrefix.
frames/src/test/java/com/checkout/frames/mock/PaymentFormConfigTestData.kt Adds test data constant for baseUrlPrefix.
frames/src/test/java/com/checkout/frames/cvvinputfield/InternalCVVComponentApiTest.kt Updates CVV API test to include baseUrlPrefix.
frames/src/test/java/com/checkout/frames/cvvinputfield/CVVComponentApiFactoryTest.kt Updates factory test for new create(...) signature.
frames/src/main/java/com/checkout/frames/screen/paymentform/model/PaymentFormConfig.kt Adds public config field baseUrlPrefix.
frames/src/main/java/com/checkout/frames/screen/paymentform/PaymentFormViewModel.kt Threads baseUrlPrefix into injector creation.
frames/src/main/java/com/checkout/frames/screen/paymentform/PaymentFormScreen.kt Passes config baseUrlPrefix into VM factory.
frames/src/main/java/com/checkout/frames/di/injector/FramesInjector.kt Threads baseUrlPrefix into CheckoutApiServiceFactory.create(...) and DI builder.
frames/src/main/java/com/checkout/frames/di/component/FramesDIComponent.kt Adds @BindsInstance baseUrlPrefix to Dagger builder.
frames/src/main/java/com/checkout/frames/cvvinputfield/api/InternalCVVComponentApi.kt Threads baseUrlPrefix into CheckoutApiServiceFactory.create(...) for CVV tokenization.
frames/src/main/java/com/checkout/frames/cvvinputfield/CVVComponentApiFactory.kt Extends CVV factory API to accept baseUrlPrefix.
example_app_frames/src/main/java/com/checkout/example/frames/ui/utils/Constants.kt Adds demo constant for regional subdomain and updates demo keys.
example_app_frames/src/main/java/com/checkout/example/frames/ui/screen/MainActivity.kt Passes regional subdomain into PaymentFormConfig.
example_app_frames/src/main/java/com/checkout/example/frames/ui/screen/HomeScreen.kt Passes regional subdomain into CheckoutApiServiceFactory.create(...).
example_app_frames/src/main/java/com/checkout/example/frames/ui/screen/CVVTokenizationScreen.kt Passes regional subdomain into CVVComponentApiFactory.create(...).
checkout/src/test/java/com/checkout/EnvironmentExtensionTest.kt Adds unit tests for Environment.toBaseUrl(...) behavior.
checkout/src/test/java/com/checkout/CheckoutApiServiceFactoryTest.kt Updates factory test for new signature.
checkout/src/main/java/com/checkout/logging/utils/EnvironmentExtension.kt Adds Environment.toBaseUrl(...) and prefix validation helper.
checkout/src/main/java/com/checkout/base/model/Environment.kt Refactors Environment enum to remove url field.
checkout/src/main/java/com/checkout/CheckoutApiServiceFactory.kt Adds baseUrlPrefix parameter and uses Environment.toBaseUrl(...) for tokenization base URL.
app/src/main/java/checkout/checkout_android/DemoActivity.java Updates demo to pass regional subdomain into PaymentFormConfig.
app/src/main/java/checkout/checkout_android/Constants.java Adds regional subdomain constant and updates demo keys.
app/src/main/java/checkout/checkout_android/CVVTokenizationActivity.java Updates demo to pass regional subdomain into CVVComponentApiFactory.create(...).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

assertEquals("https://api.checkout.com/tokens", result)
}

fun `toBaseUrl PRODUCTION returns default URL for any non-alphanumeric prefix`() {
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is missing the @Test annotation, so the invalid-prefix cases won’t run and regressions could slip through. Add @Test (and consider adding the equivalent invalid-prefix coverage for SANDBOX as well).

Copilot uses AI. Check for mistakes.
Comment on lines +84 to +88
invalidPrefixList.map { invalidPrefix ->
val result = Environment.PRODUCTION.toBaseUrl(invalidPrefix)
assertEquals(
result,
PRODUCTION_SERVER_URL,
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using map { ... } here is for side-effects only and the result is ignored. Prefer forEach (or a parameterized test) and use assertEquals(expected, actual) ordering to improve failure messages (assertEquals(PRODUCTION_SERVER_URL, result)).

Suggested change
invalidPrefixList.map { invalidPrefix ->
val result = Environment.PRODUCTION.toBaseUrl(invalidPrefix)
assertEquals(
result,
PRODUCTION_SERVER_URL,
invalidPrefixList.forEach { invalidPrefix ->
val result = Environment.PRODUCTION.toBaseUrl(invalidPrefix)
assertEquals(
PRODUCTION_SERVER_URL,
result,

Copilot uses AI. Check for mistakes.
import com.checkout.base.util.EnvironmentConstants.SANDBOX_SERVER_URL


internal fun Environment.toBaseUrl(baseUrlPrefix: String? = null) = when(this) {
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when(this) is inconsistent with Kotlin official formatting (and with when (this) used later in this same file) and may be flagged by ktlint. Use when (this) to match the repo’s enforced Kotlin style.

Suggested change
internal fun Environment.toBaseUrl(baseUrlPrefix: String? = null) = when(this) {
internal fun Environment.toBaseUrl(baseUrlPrefix: String? = null) = when (this) {

Copilot uses AI. Check for mistakes.
* Replace with Secret key from Hub in Sandbox Environment
*/
public static final String SECRET_KEY = "sk_test_568e6077-a08f-4692-9237-cc6c48dcf6aa";
public static final String SECRET_KEY = "sk_sbox_cqc26o3haljkwuns6xcfcmf2vmu";
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A (sandbox) secret key is committed into source control via SECRET_KEY. Even sandbox secret keys should not be checked in; replace this with a placeholder and load it from a secure local/developer-only mechanism (e.g., gradle properties/env var), and rotate/revoke the exposed key.

Suggested change
public static final String SECRET_KEY = "sk_sbox_cqc26o3haljkwuns6xcfcmf2vmu";
private static String loadSecretKey() {
String secretKey = System.getenv("CHECKOUT_SECRET_KEY");
if (secretKey == null || secretKey.isEmpty()) {
throw new IllegalStateException("Environment variable CHECKOUT_SECRET_KEY must be set with a valid secret key.");
}
return secretKey;
}
public static final String SECRET_KEY = loadSecretKey();

Copilot uses AI. Check for mistakes.
riskSdkUseCase = RiskSdkUseCase(environment, context, publicKey, riskSDKFramesOptions, RiskInstanceProvider),
)
baseUrlPrefix: String?
): TokenRepository {
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two spaces before { in the return type declaration (): TokenRepository {), which may be flagged by ktlint. Remove the extra whitespace to match the repo’s enforced Kotlin formatting.

Suggested change
): TokenRepository {
): TokenRepository {

Copilot uses AI. Check for mistakes.
Comment on lines +44 to 45
baseUrlPrefix: String?
): CheckoutApiService {
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CheckoutApiServiceFactory.create is a public API and baseUrlPrefix is currently a required parameter, which is a source/binary breaking change and also causes internal call sites to stop compiling (e.g., frames/src/androidTest/.../InternalCVVComponentMediatorUITest.kt still calls create(...) without this argument). Make baseUrlPrefix optional (default null) and/or provide an overload to preserve the previous signature for Kotlin/Java callers.

Suggested change
baseUrlPrefix: String?
): CheckoutApiService {
): CheckoutApiService {
return create(publicKey, environment, context, null)
}
@JvmStatic
public fun create(
publicKey: String,
environment: Environment,
context: Context,
baseUrlPrefix: String? = null,
): CheckoutApiService {

Copilot uses AI. Check for mistakes.
Comment on lines 21 to +25
public fun create(
publicKey: String,
environment: Environment,
context: Context,
baseUrlPrefix: String?,
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CVVComponentApiFactory.create is public and now requires baseUrlPrefix, which breaks existing Kotlin/Java call sites. Consider making it optional (default null) and adding an overload (e.g., via @JvmOverloads) so existing callers can continue using the 3-argument form.

Copilot uses AI. Check for mistakes.
Comment on lines 21 to +25
public fun create(
publicKey: String,
environment: Environment,
context: Context,
baseUrlPrefix: String?,
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The KDoc for CVVComponentApiFactory.create doesn’t document the new baseUrlPrefix parameter. Please add an @param baseUrlPrefix entry describing its purpose/constraints so the generated docs stay accurate.

Copilot uses AI. Check for mistakes.
SANDBOX(EnvironmentConstants.SANDBOX_SERVER_URL),
public enum class Environment {
PRODUCTION,
SANDBOX
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the public url property from Environment is a breaking API change for SDK consumers that may rely on Environment.url. Consider keeping a (possibly deprecated) url property (backed by the current default tokenization URL) or exposing a public replacement for retrieving the base URL.

Suggested change
SANDBOX
SANDBOX;
@Deprecated(
message = "Environment.url is deprecated. Use the appropriate configuration or tokenization URL accessor instead."
)
public val url: String
get() = when (this) {
PRODUCTION -> PRODUCTION_URL
SANDBOX -> SANDBOX_URL
}
private companion object {
private const val PRODUCTION_URL: String = "https://api.checkout.com/tokens"
private const val SANDBOX_URL: String = "https://api.sandbox.checkout.com/tokens"
}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants