lib 目录包含两个 Library Project:pingpp 和 pingpp_ui。 可以直接将两个 Library Project 作为依赖库,导入到你的项目。支持 Android Studio(建议)和 Eclipse。 example 文件夹里面是一个简单的接入示例,该示例仅供参考。想使用该示例,请直接将本仓库导入。 docs 目录里面是 Android SDK 的接入指南。
Android SDK 要求 Android 2.3 及以上版本 请使用 Java 7 或以上版本
导入 pingpp-android 整个项目,即可运行该demo。
需要注意: 测试微信支付,需要签名和包名与微信开放平台上的一致,才可支付成功。给出的demo并没给出正确的签名,会返回微信支付失败的结果。 导入 demo 中可能会遇到的开发环境版本问题,修改 build.gradle 中的版本
(注:依赖渠道 SDK 时,可能会和其他第三方SDK有冲突,移除依赖冲突的包就可以。如:问题二、问题三)
dependencies {
compile 'com.pingxx:pingpp-core:2.1.17' // (Ping++ 标准版 SDK) 必须添加
compile 'com.pingxx:pingpp-ui:2.1.17' // (Ping++ UI 控件) 使用 Ping++ UI 时添加
compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+' // 使用微信支付时添加,具体版本参考微信官方文档
compile 'com.pingxx:pingpp-alipay:2.1.17' // 使用支付宝时添加
compile 'com.pingxx:pingpp-upacp:2.1.17' // 使用银联支付时添加
compile 'com.pingxx:pingpp-qpay:2.1.17' // 使用QQ钱包时添加
compile 'com.pingxx:pingpp-cmbwallet:2.1.17' // 使用招行一网通时添加
}
<dependency>
<groupId>com.pingxx</groupId>
<artifactId>pingpp-core</artifactId>
<!--请将 VERSION 换成 SDK 对应的版本号-->
<version>VERSION</version>
<type>pom</type>
</dependency>
在 lib 目录中包含 pingpp(标准版 SDK)和 pingpp_ui(UI 版 SDK)资源,其中包含支付所需的 jar 包和资源包,请按需拷贝相应的文件到项目中。
- Ping++ 依赖包:
libpingpp-x.x.x
、res
资源文件和libpingpp.so
文件(必须依赖的) - 微信依赖包:
wechat-sdk-android-without-mta.jar
- 支付宝依赖包:
alipaySdkxxxxxxxx.jar
- 银联支付依赖包:
UPPayAssistEx.jar
、UPPayPluginExPro.jar
、libentryexpro.so
、libuptsmaddon.so
和assets
目录下data.bin
文件 - QQ钱包依赖包:
mqqopenpay.jar
- 招行一网通(混淆加密方式可不配置相关的参数,非混淆加密方式需配置):
cmbkeyboard.jar
和res
目录下cmb_
开头的资源文件
libpingppui-xxxx
及相关res
资源文件
(注:有些权限是需要动态注册的,如 READ_PHONE_STATE
权限)
<!-- 通用权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 银联需要的权限 -->
<uses-permission android:name="android.permission.NFC"/>
- Ping++ SDK所需要注册
<activity
android:name="com.pingplusplus.android.PaymentActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
</activity>
- 微信支付需要注册
注:
- 需要将以下“替换成自己 APK 的包名”换成在微信平台上注册填写的包名
- WxPayEntryActivity 这个类在 SDK 内部实现,开发者不需要额外实现该类
<activity-alias
android:name="替换成自己 APK 的包名.wxapi.WXPayEntryActivity"
android:exported="true"
android:targetActivity="com.pingplusplus.android.PaymentActivity" />
- 支付宝支付需要注册
<activity
android:name="com.alipay.sdk.app.H5PayActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="behind" >
</activity>
<activity
android:name="com.alipay.sdk.auth.AuthActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="behind" >
</activity>
- 银联支付需注册
<activity
android:name="com.unionpay.uppay.PayActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"/>
<activity
android:name="com.unionpay.UPPayWapActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize"/>
- QQ 钱包需注册(scheme 填写规则:qwallet + QQ 钱包中的 app_id)
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="qwalletXXXXXXXX"/>
</intent-filter>
将以上代码添加到 Ping++ SDK 注册的 Activity,如:
<activity
android:name="com.pingplusplus.android.PaymentActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="qwallet1234567890"/>
</intent-filter>
</activity>
- 招行一网通(非混淆加密方式)需注册
<service android:name="cmb.pb.cmbsafe.CmbService" android:exported="false"/>
<activity
android:name="cmb.pb.ui.PBKeyboardActivity"
android:theme="@style/CmbDialogStyleBottom" />
(招行一网通在非混淆加密方式下:需在 string.xml 中配置 cmbkb_publickey 字段,如:)
<string name="cmbkb_publickey">填写自己的 publickey</string>
charge/order 对象是一个包含支付信息的 JSON 对象,是 Ping++ SDK 发起支付的必要参数。该参数需要请求用户服务器获得,服务端生成 charge 或 order 的方式参考 服务端接入简介。SDK 中的 demo 里面提供了如何获取 charge/order 的实例方法,供用户参考。
因为 Ping++ 已经封装好了相应的调用方法,所以只需要调用支付方法即可调起支付控件: (注:该调用方法需要在主线程(UI 线程)完成)
//参数一:Activity 当前调起支付的Activity
//参数二:data 获取到的charge或order的JSON字符串
Pingpp.createPayment(YourActivity.this, data);
从 Activity 的 onActivityResult 方法中获得支付结果。支付成功后,用户服务器也会收到 Ping++ 服务器发送的异步通知。 (最终支付成功请根据服务端异步通知为准)
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//支付页面返回处理
if (requestCode == Pingpp.REQUEST_CODE_PAYMENT) {
String result = data.getExtras().getString("pay_result");
/* 处理返回值
* "success" - 支付成功
* "fail" - 支付失败
* "cancel" - 取消支付
* "invalid" - 支付插件未安装(一般是微信客户端未安装的情况)
* "unknown" - app进程异常被杀死(一般是低内存状态下,app进程被杀死)
*/
String errorMsg = data.getExtras().getString("error_msg"); // 错误信息
String extraMsg = data.getExtras().getString("extra_msg"); // 错误信息
}
}
// 注:线下渠道无支付结果返回, 返回 unknown 字段。需要从服务端获取正确的支付结果。
使用 UI 版本且不想展示 Ping++ 提供的广告请联系我们
- Ping++ SDK所需要注册
<activity
android:name="com.pingplusplus.android.PaymentActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<activity
android:name="com.pingplusplus.ui.PayActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<activity
android:name="com.pingplusplus.ui.PaySuccessActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"/>
- 微信支付需要注册
注:
- 需要将以下“替换成自己 APK 的包名”换成在微信平台上注册填写的包名
- WxPayEntryActivity 这个类在 SDK 内部实现,开发者不需要额外实现该类
<activity-alias
android:name="替换成自己 APK 的包名.wxapi.WXPayEntryActivity"
android:exported="true"
android:targetActivity="com.pingplusplus.android.PaymentActivity" />
- 支付宝支付需要注册
<activity
android:name="com.alipay.sdk.app.H5PayActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="behind" >
</activity>
<activity
android:name="com.alipay.sdk.auth.AuthActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="behind" >
</activity>
- 银联支付需注册
<activity
android:name="com.unionpay.uppay.PayActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"/>
<activity
android:name="com.unionpay.UPPayWapActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize"/>
- QQ 钱包需注册(scheme 填写规则:qwallet + QQ 钱包中的 app_id)
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="qwalletXXXXXXXX"/>
</intent-filter>
将以上代码添加到 Ping++ SDK 注册的 Activity,如:
<activity
android:name="com.pingplusplus.android.PaymentActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="qwallet1234567890"/>
</intent-filter>
</activity>
- 招行一网通(非混淆加密方式)需注册
<service android:name="cmb.pb.cmbsafe.CmbService" android:exported="false"/>
<activity
android:name="cmb.pb.ui.PBKeyboardActivity"
android:theme="@style/CmbDialogStyleBottom" />
(招行一网通在非混淆加密方式下:需在 string.xml 中配置 cmbkb_publickey 字段,如:)
<string name="cmbkb_publickey">填写自己的 publickey</string>
使用选择渠道面板
// 设置选择渠道面板
CHANNELS[] channels = new CHANNELS[]{CHANNELS.ALIPAY, CHANNELS.WX, CHANNELS.UPACP,
CHANNELS.BFB_WAP, CHANNELS.JDPAY_WAP, CHANNELS.QPAY,
CHANNELS.CMB_WALLET, CHANNELS.YEEPAY_WAP};
PingppUI.enableChannels(channels);
// 参数一: context 上下文对象
// 参数二: ChannelListener 选择渠道回调类
PingppUI.showPaymentChannels(context, new ChannelListener() {
@Override public void selectChannel(String channel) {
// channel 为用户选择的支付渠道
}
}
调起支付
// 参数一: context 上下文对象
// 参数二: data charge/order 字符串
// 参数三: PaymentHandler 支付结果回调类
PingppUI.createPay(context, data, new PaymentHandler() {
@Override public void handlePaymentResult(Intent data) {
int code = data.getExtras().getInt("code");
String result = data.getExtras().getString("result");
}
});
// 参数一: context 上下文对象
// 参数二: bill 获取charge参数字符串 例: {"order_no":"123456789", "amount":10, "custom_params":{"extra1":"extra1"}}
// 参数三: CHARGE_URL 获取charge的URL
// 参数四: PaymentHandler 支付结果回调类
PingppUI.showPaymentChannels(this, bill, CHARGE_URL, new PaymentHandler() {
@Override public void handlePaymentResult(Intent data) {
// code:支付结果码 -2:服务端错误、 -1:失败、 0:取消、1:成功
int code = data.getExtras().getInt("code");
// result:支付结果信息
String result = data.getExtras().getString("result");
}
});
(注:将以下对应渠道的混淆代码加到主 module 以及该 SDK 依赖所在的 module 中,不然会出现 jar 包重复或者找不到该类的问题,如:问题二)
# Ping++ 混淆过滤
-dontwarn com.pingplusplus.**
-keep class com.pingplusplus.** {*;}
# 支付宝混淆过滤
-dontwarn com.alipay.**
-keep class com.alipay.** {*;}
# 微信或QQ钱包混淆过滤
-dontwarn com.tencent.**
-keep class com.tencent.** {*;}
# 银联支付混淆过滤
-dontwarn com.unionpay.**
-keep class com.unionpay.** {*;}
# 招行一网通混淆过滤
-keepclasseswithmembers class cmb.pb.util.CMBKeyboardFunc {
public <init>(android.app.Activity);
public boolean HandleUrlCall(android.webkit.WebView,java.lang.String);
public void callKeyBoardActivity();
}
# 内部WebView混淆过滤
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
SDK 提供了日志功能,默认日志为关闭状态。 开发者可以通过下面设置打开日志开关。通过 PING++ 来对日志进行筛选。
//开启调试模式
Pingpp.DEBUG = true;
- Pingpp Android SDK 可能会与友盟、百度地图等其他第三方 jar 包冲突,当同时使用这些 jar 包的时候用户需要根据情况判断保留哪一方的 jar 包。
- 新版建议使用 Android Studio
- 请勿直接使用客户端支付结果作为最终判定订单状态的依据,由于 Ping++ 没有参与你的客户端和第三方渠道的交互,无法保证客户端支付结果的安全性,建议订单状态的更新对比客户端的渠道同步回调信息和服务端的 Ping++ Webhooks 通知来确定是否修改。
- 报错原因: 微信验证 apk 的签名包名失败。
- 解决方案:
- 项目的 package 名字、AndroidManifest.xml 里面的包名,必须和微信开放平台注册的一致;
- 必须打包成为发布版本的 apk,apk 签名必须和在微信开放平台注册的一致,微信开放平台签名要求: MD5,无冒号;
- 清理微信缓存;
- 如果签名包名均正确,仍旧返回 -1 报错,请检查时间戳格式是否有问题或重置微信开放平台的安卓版本的签名包名。
- 报错Log:
Error:Execution failed for task ':app:transformClassesWithJarMergingForDebug'.
com.android.build.api.transform.TransformException:
java.util.zip.ZipException: duplicate entry: a/a/a/a.class
-
报错原因:
- 没有加过滤混淆的代码
- 有重复的jar包存在
-
解决方案:
- 加上混淆过滤的代码(出现 a/a/a/a.class 的 log 时)
- 删除重复的 jar 包(可以是第三方SDK中的,也可以是 Ping++ SDK 中的jar包)
-
报错原因: Ping++ SDK 提供了 armeabi、armeabi-v7a 而其他第三方 SDK(如:高德地图)提供了 armeabi, 当手机是 armeabi-v7a 的会去加载 armeabi-v7a 包下的 so 文件 这是会报其他第三方 SDK (如:高德地图)的 so 文件找不到,而你上面的代码在打包的时候就只打包了 armeabi,所以只会去 armeabi 包下找,因此不会出现报错 建议使用各种SDK时保持相同的so文件。
-
解决方案: 在 build.gradle 中设置 ndk
ndk {
//选择要添加的对应cpu类型的.so库。选择的so文件需要各种SDK保持一致
abiFilters 'armeabi', 'x86'
// 还可以添加 'x86_64', 'mips', 'mips64',, 'armeabi-v7a', 'armeabi-v8a'
}
java.lang.ClassNotFoundException: org.simalliance.openmobileapi.SEService
或 can’t find reference class org.openmobileapi.SEService
-
报错原因: 缺少
org.simalliance.openmobileapi.SEService
, 编译失败 -
解决方案: 将example中libs下的
org.simalliance.openmobileapi.jar
拷到项目中依赖,但不要打包进apk中,有些手机会存在这个jar包dependencies { provided files('libs/org.simalliance.openmobileapi.jar') //使用provided,不打包进apk }
-
报错原因: 没有在
string.xml
中配置cmbkb_publickey
字段 -
解决方案: 在自己项目中
res/values/string.xml
下配置该字段<string name="cmbkb_publickey">填写自己的 publickey </string>