最近集成完PayPal支付,记录一下集成注意事项。
一、PayPal版本选择
由于官方不再支持旧版的"PayPal-Android-SDK",所以决定直接集成"Native Checkout SDK"。
二、集成环境
我是在Macos上开发,之前一直用的Android Studio 3.2.0版本,但是Native Checkout SDK的SDK和 demo都是用的kotlin,集成过程中一直有各种问题,最后直接更新到 Android Studio 4.2.2版本就成功集成了。
三、集成遇到的问题
1、官司方指导第二步“2.Add the SDK to your app”中,这段代码里面的lotlinOptions导致我编译失败,所以把这个删掉了。
android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
/* 删除这段
kotlinOptions {
jvmTarget = "1.8"
}
*/
}
2、在支付的时候,跳转到网页后,一直提示"此操作好像不受支持。请返回并报告此错,以便我们今后为您提供支持。(client_id或redirect_url无效)"。这个问题是折腾最久的,主要检查以下几个地方
1)环境和对应的client_id是否匹配,如果正式环境用了沙盒的clientid,是会报这个错的。
2)集成时比较大意,没有仔细看"Know before you code" ,导致缺少了一些配置。
2.1)在后台设置Return URL,同时要在app的AndroidManifest里面配置一下
2.2)勾选 Log in with PayPal ,并且勾选它里面的Full name和Email,填写隐私政策和用户协议网址。
处理完这几点,我这边的支付也就能成功了。
————不过这里有一点要注意的是,Live环境下,默认只允许打开Full name这个属性,Email属性是无法打开的,导致Sandbox能支付成功,但Live不行。根据提示,我们必须发邮件给help-loginappreview@paypal.com请求打开Email属性才可以。
3、后台那边要求提供paymentId和orderId,但是在onCaptureComplete成功后,获取paymentId却一直是null,orderId正常。最终是后台那边修改后,只需要orderId就搞定了。
---------------------------------------2022-03-22补充------------------------------
开发最悲哀的就是集成过一次,过几个月再去集成的时候,又一直失败。最近因为另一个项目也需要集成paypal支付,于是按部就班的从原来那个项目把关键代码都拷过来了,这里大概贴一下:
//1、在build.gradle中添加
dependencies {
implementation 'com.paypal.checkout:android-sdk:0.3.1'
}
//2、全局初始化一次
{
CheckoutConfig config = new CheckoutConfig(
"Application实例",
"client ID",
(g_paypalSandboxEnvirment ? com.paypal.checkout.config.Environment.SANDBOX : com.paypal.checkout.config.Environment.LIVE),
"包名://paypalpay",
CurrencyCode.USD,
UserAction.PAY_NOW,
new SettingsConfig(
true,
false
)
);
PayPalCheckout.setConfig(config);
}
//3、在xml中集成PayPalButton
<com.paypal.checkout.paymentbutton.PayPalButton
android:id="@+id/payPalButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
//4、监听支付结果
payPalButton.setup(
new CreateOrder() {
@Override
public void create(@NotNull CreateOrderActions createOrderActions) {
Log.i("CaptureOrder", "create: ");
}
},
new OnApprove() {
@Override
public void onApprove(@NotNull Approval approval) {
Log.i("CaptureOrder", "getOrderId: " + approval.getData().getOrderId());
}
},
new OnCancel() {
@Override
public void onCancel() {
Log.d("CaptureOrder", "Buyer cancelled the PayPal experience.");
}
},
new OnError() {
@Override
public void onError(@NotNull ErrorInfo errorInfo) {
Log.d("CaptureOrder", String.format("Error: %s", errorInfo));
}
}
);
可以却碰到了几个问题:
1、因为平常都是用java开发,而PayPal支付是用的kotlin,会碰到几个错误:
1)org.jetbrains.annotations.NotNull找不到
2)找不到kotlin.jvm.functions.Function1的类文件
解决办法:打开Tools->Kotlin->Configure Kotlin in Project,对module配置kotlin支持就行了。可以参考这个博客https://blog.csdn.net/qq_32886769/article/details/105695369
只不过在提示Choose Configurator时注意选择Android With Gradle
2、然后又碰到错误:AAPT: error: resource android:attr/lStar not found.
解决办法:在第1步中支持kotlin后,在gradle中有自动加入这行代码:
implementation "androidx.core:core-ktx:+",如果没找到可全局搜一下。
我们需要把它改为 implementation "androidx.core:core-ktx:1.6.0"
啥原因我也解释不了,参考博客https://www.zhihu.com/question/484282465
3、以上2步后,可以正常运行了,但是CheckoutConfig初始化时,直接挂掉了。
2022-03-22 15:51:15.769 28696-28696/com.paypal.mykj W/System.err: java.lang.ExceptionInInitializerError
2022-03-22 15:51:15.769 28696-28696/com.paypal.mykj W/System.err: at okhttp3.internal.platform.Platform.get(Platform.java:85)
2022-03-22 15:51:15.769 28696-28696/com.paypal.mykj W/System.err: at okhttp3.OkHttpClient.newSslSocketFactory(OkHttpClient.java:263)
2022-03-22 15:51:15.769 28696-28696/com.paypal.mykj W/System.err: at okhttp3.OkHttpClient.<init>(OkHttpClient.java:229)
2022-03-22 15:51:15.769 28696-28696/com.paypal.mykj W/System.err: at okhttp3.OkHttpClient$Builder.build(OkHttpClient.java:1015)
2022-03-22 15:51:15.769 28696-28696/com.paypal.mykj W/System.err: at com.paypal.pyplcheckout.services.api.NetworkObject$okHttpClient$2.invoke(NetworkObject.kt:30)
2022-03-22 15:51:15.769 28696-28696/com.paypal.mykj W/System.err: at com.paypal.pyplcheckout.services.api.NetworkObject$okHttpClient$2.invoke(NetworkObject.kt:11)
2022-03-22 15:51:15.769 28696-28696/com.paypal.mykj W/System.err: at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
2022-03-22 15:51:15.769 28696-28696/com.paypal.mykj W/System.err: at com.paypal.pyplcheckout.services.api.NetworkObject.getOkHttpClient(Unknown Source:2)
2022-03-22 15:51:15.769 28696-28696/com.paypal.mykj W/System.err: at com.paypal.pyplcheckout.di.NetworkModule.providesOkHttpClient(NetworkModule.kt:16)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at com.paypal.pyplcheckout.di.NetworkModule_ProvidesOkHttpClientFactory.providesOkHttpClient(NetworkModule_ProvidesOkHttpClientFactory.java:29)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at com.paypal.pyplcheckout.di.NetworkModule_ProvidesOkHttpClientFactory.get(NetworkModule_ProvidesOkHttpClientFactory.java:21)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at com.paypal.pyplcheckout.di.NetworkModule_ProvidesOkHttpClientFactory.get(NetworkModule_ProvidesOkHttpClientFactory.java:8)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at com.paypal.pyplcheckout.di.DaggerSdkComponent.getRetrieveFundingEligibilityAction(DaggerSdkComponent.java:298)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at com.paypal.checkout.PayPalCheckout$updateFundingEligibility$1.invokeSuspend(PayPalCheckout.kt:84)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at android.os.Handler.handleCallback(Handler.java:938)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at android.os.Looper.loop(Looper.java:223)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at android.app.ActivityThread.main(ActivityThread.java:7664)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at java.lang.reflect.Method.invoke(Native Method)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: Caused by: java.lang.IllegalStateException: Expected Android API level 21+ but was 30
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at okhttp3.internal.platform.AndroidPlatform.buildIfSupported(AndroidPlatform.java:238)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at okhttp3.internal.platform.Platform.findPlatform(Platform.java:202)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: at okhttp3.internal.platform.Platform.<clinit>(Platform.java:79)
2022-03-22 15:51:15.770 28696-28696/com.paypal.mykj W/System.err: ... 24 more
因为看样子跟okhttp有关,于是检查了下我集成的okhttp版本,是3.8.0,于是改成了4.6.0
//旧版本干掉
implementation 'com.squareup.okhttp3:okhttp:3.8.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'
implementation 'com.squareup.okio:okio:1.7.0'
//支持新版本
implementation "com.squareup.okhttp3:okhttp:4.6.0"
4、这时候初始化也正常了,但是还有个大坑,直接在我加载PaypalButton的时候挂了
2022-03-22 15:55:45.000 29484-29484/com.paypal.mykj W/System.err: android.view.InflateException: Binary XML file line #193 in com.paypal.mykj:layout/check_result_dialog_view: Binary XML file line #193 in com.paypal.mykj:layout/check_result_dialog_view: Error inflating class com.paypal.checkout.paymentbutton.PayPalButton
2022-03-22 15:55:45.000 29484-29484/com.paypal.mykj W/System.err: Caused by: android.view.InflateException: Binary XML file line #193 in com.paypal.mykj:layout/check_result_dialog_view: Error inflating class com.paypal.checkout.paymentbutton.PayPalButton
这下有点懵了,怎么集成PayPalButton这么还能出错,找了一通没找到任何原因。后来再仔细看了下日志,发现有这么一段
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.AppCompat (or a descendant).
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: at com.google.android.material.internal.ThemeEnforcement.checkTheme(ThemeEnforcement.java:243)
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: at com.google.android.material.internal.ThemeEnforcement.checkAppCompatTheme(ThemeEnforcement.java:213)
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: at com.google.android.material.internal.ThemeEnforcement.checkCompatibleTheme(ThemeEnforcement.java:148)
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: at com.google.android.material.internal.ThemeEnforcement.obtainStyledAttributes(ThemeEnforcement.java:76)
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: at com.google.android.material.progressindicator.BaseProgressIndicatorSpec.<init>(BaseProgressIndicatorSpec.java:79)
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: at com.google.android.material.progressindicator.CircularProgressIndicatorSpec.<init>(CircularProgressIndicatorSpec.java:75)
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: at com.google.android.material.progressindicator.CircularProgressIndicatorSpec.<init>(CircularProgressIndicatorSpec.java:67)
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: at com.google.android.material.progressindicator.CircularProgressIndicatorSpec.<init>(CircularProgressIndicatorSpec.java:62)
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: at com.google.android.material.progressindicator.CircularProgressIndicator.createSpec(CircularProgressIndicator.java:80)
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: at com.google.android.material.progressindicator.CircularProgressIndicator.createSpec(CircularProgressIndicator.java:51)
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: at com.google.android.material.progressindicator.BaseProgressIndicator.<init>(BaseProgressIndicator.java:143)
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: at com.google.android.material.progressindicator.CircularProgressIndicator.<init>(CircularProgressIndicator.java:71)
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: at com.google.android.material.progressindicator.CircularProgressIndicator.<init>(CircularProgressIndicator.java:66)
2022-03-22 15:55:45.002 29484-29484/com.paypal.mykj W/System.err: ... 42 more
这才发现,原来是AndroidManifest中的Application主题设置错误,这项目原来是别人搞的,他的主题设置的是 android:theme="@android:style/Theme.Holo.Light",而CircularProgressIndicator需要的主题是Theme.AppCompat。把这个改掉,总算是堂堂正正的跑起来了。心情舒畅了。。。
---------------------------------------------------------------------------------------
本文主要是自己做个笔记,也希望大家在集成PayPal时少踩几个坑。有不到之处敬请谅解。