Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

カードフォームの追加属性項目(メール・電話番号)をサポートする #80

Merged
merged 21 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 21 additions & 39 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,27 @@ on:
env:
FLUTTER_CHANNEL: stable
CACHE_NUMBER: 0 # increment to truncate cache
IOS_SIMULATOR_DEVICE: iPhone 13 Pro Max
IOS_SIMULATOR_RUNTIME: iOS-15-2
USER_JAVA_VERSION: 11.x
IOS_SIMULATOR_DEVICE: iPhone 15 Pro
IOS_SIMULATOR_RUNTIME: iOS-17-5
USER_JAVA_VERSION: 17

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
# setup flutter
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: ${{ env.USER_JAVA_VERSION }}
- uses: subosito/flutter-action@v1
distribution: "zulu"
- uses: subosito/flutter-action@v2
with:
channel: ${{ env.FLUTTER_CHANNEL }}
# configure cache
- name: Cache Flutter
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: |
/Users/runner/hostedtoolcache/flutter
Expand All @@ -43,30 +44,21 @@ jobs:

build-android:
needs: build
runs-on: macos-latest
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
# setup flutter
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: ${{ env.USER_JAVA_VERSION }}
- uses: subosito/flutter-action@v1
distribution: "zulu"
- uses: subosito/flutter-action@v2
with:
channel: ${{ env.FLUTTER_CHANNEL }}
# configure cache
- name: Cache Gradle
uses: actions/cache@v2
with:
path: |
~/.gradle/cache
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ env.CACHE_NUMBER }}-${{ hashFiles('**/*/*.gradle*') }}
restore-keys: |
${{ runner.os }}-gradle-${{ env.CACHE_NUMBER }}-
${{ runner.os }}-gradle-
- uses: gradle/actions/setup-gradle@v3
- name: Cache Flutter
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: |
/Users/runner/hostedtoolcache/flutter
Expand All @@ -82,7 +74,7 @@ jobs:
- name: Run e2e test on Android Emulator
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 29
api-level: 34
arch: x86_64
profile: pixel
script: make driver-test
Expand All @@ -93,24 +85,16 @@ jobs:
timeout-minutes: 30
steps:
# setup flutter
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: ${{ env.USER_JAVA_VERSION }}
- uses: subosito/flutter-action@v1
distribution: "zulu"
- uses: subosito/flutter-action@v2
with:
channel: ${{ env.FLUTTER_CHANNEL }}
# configure cache
- name: Cache CocoaPods
uses: actions/cache@v2
with:
path: example/ios/Pods
key: ${{ runner.os }}-pods-${{ env.CACHE_NUMBER }}-${{ hashFiles('example/ios/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-${{ env.CACHE_NUMBER }}-
${{ runner.os }}-pods-
- name: Cache Flutter
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: |
/Users/runner/hostedtoolcache/flutter
Expand All @@ -132,5 +116,3 @@ jobs:
xcrun simctl boot "${UDID}"
- name: Run e2e test
run: make driver-test


2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ dependencies:

.PHONY: check
check:
flutter format --set-exit-if-changed --dry-run lib/ example/lib
dart format --set-exit-if-changed -o none lib/ example/lib
flutter analyze
flutter test

Expand Down
2 changes: 0 additions & 2 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ linter:
- prefer_function_declarations_over_variables
- unnecessary_lambdas
# parameters
- prefer_equal_for_default_values
# variables
- avoid_init_to_null
# members
Expand Down Expand Up @@ -73,7 +72,6 @@ linter:
# members
- use_setters_to_change_properties
- avoid_setters_without_getters
- avoid_returning_null # avoid
- avoid_returning_this # avoid
# types
- type_annotate_public_apis # prefer
Expand Down
25 changes: 16 additions & 9 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:4.1.3'
classpath 'com.android.tools.build:gradle:8.6.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Expand All @@ -58,27 +58,34 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

android {
compileSdkVersion 33

if (project.android.hasProperty("namespace")) {
namespace 'jp.pay.flutter'
}
compileSdk 34
buildFeatures {
buildConfig true
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
minSdkVersion 16
targetSdkVersion 33
minSdk 21
buildConfigField "String", "VERSION_NAME", "\"$VERSION_NAME\""
}
lintOptions {
disable 'InvalidPackage'
checkAllWarnings true
warningsAsErrors true
disable 'AndroidGradlePluginVersion', 'InvalidPackage', 'GradleDependency', 'NewerVersionAvailable'
}
kotlin {
jvmToolchain 17
}
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "jp.pay:payjp-android:$payjpSdkVersion"
implementation "jp.pay:payjp-android-cardio:$payjpSdkVersion"

implementation "androidx.appcompat:appcompat:1.2.0"
implementation "androidx.appcompat:appcompat:1.7.0"
implementation "io.card:android-sdk:5.5.1"
implementation 'com.google.android.gms:play-services-base:18.1.0'
}
2 changes: 1 addition & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
# SOFTWARE.
#

org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.parallel=true
org.gradle.daemon=true
org.gradle.configureondemand=true
Expand Down
3 changes: 1 addition & 2 deletions android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,5 @@
~ SOFTWARE.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.pay.flutter">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>
10 changes: 8 additions & 2 deletions android/src/main/kotlin/jp/pay/flutter/CardFormModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import jp.pay.android.Payjp
import jp.pay.android.PayjpCardForm
import jp.pay.android.PayjpTokenBackgroundHandler
import jp.pay.android.PayjpTokenBackgroundHandler.CardFormStatus
import jp.pay.android.model.ExtraAttribute
import jp.pay.android.model.TenantId
import jp.pay.android.model.Token
import jp.pay.android.model.toJsonValue
Expand Down Expand Up @@ -66,13 +67,18 @@ internal class CardFormModule(

// handle MethodCall

fun startCardForm(result: MethodChannel.Result, tenantId: TenantId?, @PayjpCardForm.CardFormFace face: Int) {
fun startCardForm(
result: MethodChannel.Result,
tenantId: TenantId?,
@PayjpCardForm.CardFormFace face: Int,
extraAttributes: Array<ExtraAttribute<*>>) {
currentActivity()?.let { activity ->
Payjp.cardForm().start(
activity = activity,
requestCode = requestCodeCardForm,
tenant = tenantId,
face = face
face = face,
extraAttributes = extraAttributes
)
result.success(null)
} ?: result.pluginError("Activity not found.")
Expand Down
36 changes: 15 additions & 21 deletions android/src/main/kotlin/jp/pay/flutter/PayjpFlutterPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,7 @@
package jp.pay.flutter

import android.content.Context
import android.os.Build
import android.util.Log
import androidx.core.os.LocaleListCompat
import com.google.android.gms.common.GooglePlayServicesNotAvailableException
import com.google.android.gms.common.GooglePlayServicesRepairableException
import com.google.android.gms.security.ProviderInstaller
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
Expand All @@ -44,6 +39,7 @@ import jp.pay.android.PayjpCardForm
import jp.pay.android.PayjpConfiguration
import jp.pay.android.cardio.PayjpCardScannerPlugin
import jp.pay.android.model.ClientInfo
import jp.pay.android.model.ExtraAttribute
import jp.pay.android.model.TenantId
import java.util.Locale

Expand Down Expand Up @@ -116,7 +112,6 @@ class PayjpFlutterPlugin: MethodCallHandler, FlutterPlugin, ActivityAware {
.setPublisher("payjp")
.build()
val tdsRedirectKey = call.argument<String>("threeDSecureRedirectKey")
activateModernTls(debugEnabled)
Payjp.init(PayjpConfiguration.Builder(publicKey = publicKey)
.setDebugEnabled(debugEnabled)
.setTokenBackgroundHandler(cardFormModule)
Expand All @@ -135,7 +130,20 @@ class PayjpFlutterPlugin: MethodCallHandler, FlutterPlugin, ActivityAware {
face = PayjpCardForm.FACE_CARD_DISPLAY
}
}
cardFormModule?.startCardForm(result, tenantId, face) ?: result.pluginError("plugin not attached.")
val extraAttributes: Array<ExtraAttribute<*>> = listOfNotNull(
ExtraAttribute.Email(call.argument<String>("extraAttributesEmailPreset"))
.takeIf { call.argument<Boolean>("extraAttributesEmailEnabled") ?: false },
ExtraAttribute.Phone(
region = call.argument<String>("extraAttributesPhonePresetRegion") ?: "JP",
number = call.argument<String>("extraAttributesPhonePresetNumber")
).takeIf { call.argument<Boolean>("extraAttributesPhoneEnabled") ?: false }
).toTypedArray()
cardFormModule?.startCardForm(
result = result,
tenantId = tenantId,
face = face,
extraAttributes = extraAttributes
) ?: result.pluginError("plugin not attached.")
}
ChannelContracts.SHOW_TOKEN_PROCESSING_ERROR -> {
val message = checkNotNull(call.argument<String>("message"))
Expand All @@ -146,18 +154,4 @@ class PayjpFlutterPlugin: MethodCallHandler, FlutterPlugin, ActivityAware {
}
else -> result.notImplemented()
}

private fun activateModernTls(debugEnabled: Boolean) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
try {
applicationContext?.let {
ProviderInstaller.installIfNeeded(it)
}
} catch (e: GooglePlayServicesRepairableException) {
if (debugEnabled) Log.e("payjp-android", "error ssl setup", e)
} catch (e: GooglePlayServicesNotAvailableException) {
if (debugEnabled) Log.e("payjp-android", "error ssl setup", e)
}
}
}
}
63 changes: 24 additions & 39 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,61 +20,46 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
plugins {
id "com.android.application"
id "kotlin-android"
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin"
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 33
namespace = "jp.pay.flutter.example"
compileSdk = flutter.compileSdkVersion

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "jp.pay.flutter.example"
minSdkVersion 21
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
applicationId = "jp.pay.flutter.example"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
signingConfig = signingConfigs.debug
}
}
lint {
checkReleaseBuilds false
disable 'InvalidPackage'
}
namespace 'jp.pay.flutter.example'
}

flutter {
source '../..'
source = "../.."
}
Loading