android第三方支付的接入(支付宝,微信,银联,京东,百度等)

前言

现在很多应用都需要接入第三方支付sdk,支付方式有很多,常用的支付宝,微信,银联,百度,京东等等,如果一一接入那就太麻烦了,能不能只接入一个sdk但是常用支付方式都能使用呢?ping++帮我们实现了这个功能。这篇博客是我结合开发文档和官方demo写的,使得ping++ sdk的接入非常清晰,下面的代码也是摘自官方demo。

1. ping++简介

ping++是一个聚合支付接口,简单来说,就是它的sdk,就可以使用各种支付方式,而不用自己再一个一个接入。ping++适配了 Android,iOS 和 HTML5 三种移动端平台以及 PC 端网页这4种平台。

  • Server SDK

目前 Server SDK 支持 PHP、Java、Python、Node.js、Ruby、Go、C# 七种语言。

  • Client SDK

Client SDK 支持 Android 终端、iOS 终端 、手机网页和 PC 网页这四种平台,分别对应 Android、iOS 、 HTML5 和 PC 这四种 Client SDK。

  • 壹收款

为了让用户接入有更好的体验,Ping++ 在 Client SDK 的基础上推出了「壹收款」。它提供内嵌支付页面和支付完成页面,不仅进一步降低了接入的开发成本,同时优化了支付流程体验。你可以选择 Server SDK + Client SDK 接入支付,也可以通过壹收款 + Server SDK 接入支付,壹收款在支付中的作用等同于 Client SDK。目前 Ping++ 支持 iOS、Android 和 HTML5 的壹收款,具体可以通过 SDK 交易流程查看壹收款是如何交易的。

Server是服务器端,移动端是Client SDK和壹收款。壹收款其实就是内嵌了这几种支付方式,自己提供了支付方式选择的页面和支付的回调。是下面这个样子:

image

壹收款有如下缺点:

  1. 支付方式页面的样式貌似不能改(不确定,如果我说的不对,欢迎指正),就是上面大家看到的那个样子

  2. 壹收款可能会与友盟、百度地图等其他第三方 jar 包冲突,当同时使用这些 jar 包的时候用户需要根据情况判断保留哪一方的 jar 包。

综上,本篇博客只看Client SDK的 android接入。

ping++支持的android端的支付方式有:支付宝,微信,京东,百度,银联。

ping++有2中模式,Test 模式和Live 模式。

  • Test 模式

Test 模式供开发测试时使用。因为 Test 模式把支付流程与渠道参数隔离开,所以开发可以与渠道申请同时进行,从而缩短接入调试时间。Test 模式中发起模拟交易不会调用真实支付控件,支付时客户端会跳转到 Ping++ 提供的模拟支付页面。

  • Live 模式

Live 模式是应用上线的模式。该模式下会发生真实的交易,调起真实的支付控件产生真实的资金流动,所以请确保在 Test 模式下所有的功能都测试通过后,再切换到 Live 模式。

我们下面的测试程序使用Test模式。这是效果图:

image

image

2. 接入方法

2.1 导入jar包

ping++代码在github上托管,点击下载:PingPlusPlus/pingpp-android

下载完后,把项目pingpp-android-master下的lib文件夹拷到你的项目中,和app在同级目录,然后在seeting.gradle中加入:

include ':lib:pingpp'
include ':lib:bdwallet_pay_sdk'
include ':lib:pingpp_one'

或者 菜单 -> file -> new -> import module,定位到刚才下载的pingpp-android-master下的lib文件夹,分别把这三个项目引入。

注意:

通过import引入的项目都和app项目是同级目录,而第一种方式是把他们都放到lib文件夹中。

在build.gradle中加入:

dependencies {
	compile project(':lib:pingpp')
	compile project(':lib:pingpp_one')
	compile project(':lib:bdwallet_pay_sdk')
}

2.2 加权限

manifest中加入:

<!-- 通用权限 -->
<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" />
<uses-permission-sdk-23 android:name="android.permission.READ_PHONE_STATE" />
<uses-permission-sdk-23 android:name="android.permission.NFC" />

<!-- 百度支付需要的权限 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.READ_SMS" />

2.3 注册 activity

	<!-- Ping++ SDK -->
	<activity
    	android:name="com.pingplusplus.android.PaymentActivity"
    	android:configChanges="orientation|screenSize"
   	 	android:launchMode="singleTop"
    	android:theme="@android:style/Theme.Translucent.NoTitleBar" />

	<!-- 微信支付 -->
	<activity-alias
    	android:name=".wxapi.WXPayEntryActivity"
    	android:exported="true"
    	android:targetActivity="com.pingplusplus.android.PaymentActivity" />

	<!-- 支付宝 -->
	<activity
    	android:name="com.alipay.sdk.app.H5PayActivity"
    	android:configChanges="orientation|keyboardHidden|navigation"
    	android:exported="false"
    	android:screenOrientation="behind" />
	<activity
    	android:name="com.alipay.sdk.auth.AuthActivity"
    	android:configChanges="orientation|keyboardHidden|navigation"
    	android:exported="false"
    	android:screenOrientation="behind" />

	<!-- 银联支付 -->
	<activity android:name="com.unionpay.uppay.PayActivity" />

	<!-- 百度钱包 -->
	<activity
    	android:name="com.baidu.paysdk.login.LoginActivity"
    	android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    	android:excludeFromRecents="true"
    	android:exported="false"
    	android:theme="@style/EbpayThemeActivityWelcome"
    	android:windowSoftInputMode="stateHidden" />
	<activity
    	android:name="com.baidu.paysdk.ui.WelcomeActivity"
    	android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    	android:excludeFromRecents="true"
    	android:exported="@bool/bd_wallet_switch_global_debug"
    	android:theme="@style/EbpayThemeActivityWelcome"
    	android:screenOrientation="portrait"
    	android:windowSoftInputMode="stateHidden" />
	<activity
    	android:name="com.baidu.paysdk.ui.OrderHomeActivity"
    	android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    	android:excludeFromRecents="true"
    	android:exported="@bool/bd_wallet_switch_global_debug"
    	android:hardwareAccelerated="false"
    	android:screenOrientation="portrait"
    	android:theme="@style/EbpayThemeActivit"
   	 	android:windowSoftInputMode="stateHidden" />
	<activity
    	android:name="com.baidu.paysdk.ui.PayResultActivity"
    	android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    	android:excludeFromRecents="true"
    	android:exported="@bool/bd_wallet_switch_global_debug"
    	android:screenOrientation="portrait"
    	android:theme="@style/EbpayThemeActivit"
   	 	android:windowSoftInputMode="stateHidden" />
	<activity
    	android:name="com.baidu.paysdk.ui.PcPwdCheckActivity"
    	android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    	android:excludeFromRecents="true"
    	android:exported="@bool/bd_wallet_switch_global_debug"
    	android:theme="@style/EbpayThemeActivit"
    	android:screenOrientation="portrait"
    android:windowSoftInputMode="stateVisible" />
<activity
    android:name="com.baidu.paysdk.ui.PwdCheckActivity"
    android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    android:excludeFromRecents="true"
    android:exported="@bool/bd_wallet_switch_global_debug"
    android:theme="@style/EbpayThemeActivit"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateVisible" />
<activity
    android:name="com.baidu.paysdk.ui.PwdSetAndConfirmActivity"
    android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    android:excludeFromRecents="true"
    android:exported="@bool/bd_wallet_switch_global_debug"
    android:theme="@style/EbpayThemeActivit"
    android:windowSoftInputMode="stateVisible" />
<activity
    android:name="com.baidu.paysdk.ui.PwdPayActivity"
    android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    android:excludeFromRecents="true"
    android:exported="@bool/bd_wallet_switch_global_debug"
    android:theme="@style/EbpayThemeActivitTranslucent"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateVisible|adjustResize" />
<activity
    android:name="com.baidu.paysdk.ui.PwdPaySmsActivity"
    android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    android:excludeFromRecents="true"
    android:exported="@bool/bd_wallet_switch_global_debug"
    android:theme="@style/EbpayThemeActivitTranslucent"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateHidden" />
<activity
    android:name="com.baidu.paysdk.ui.WebViewActivity"
    android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    android:excludeFromRecents="true"
    android:exported="@bool/bd_wallet_switch_global_debug"
    android:screenOrientation="portrait"
    android:theme="@style/EbpayThemeActivit"
    android:windowSoftInputMode="stateHidden" />
<activity
    android:name="com.baidu.paysdk.ui.BindCardNoActivity"
    android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    android:excludeFromRecents="true"
    android:exported="@bool/bd_wallet_switch_global_debug"
    android:theme="@style/EbpayThemeActivit"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateHidden" />
<activity
    android:name="com.baidu.paysdk.ui.BindCardDetailActivity"
    android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    android:excludeFromRecents="true"
    android:exported="@bool/bd_wallet_switch_global_debug"
    android:theme="@style/EbpayThemeActivit"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateVisible|adjustPan" />
<activity
    android:name="com.baidu.paysdk.ui.BindCardDetailCredit2Activity"
    android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    android:excludeFromRecents="true"
    android:exported="@bool/bd_wallet_switch_global_debug"
    android:screenOrientation="portrait"
    android:theme="@style/EbpayThemeActivit"
    android:windowSoftInputMode="stateVisible|adjustPan" />
<activity
    android:name="com.baidu.paysdk.ui.BindCardDetailCreditActivity"
    android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    android:excludeFromRecents="true"
    android:exported="@bool/bd_wallet_switch_global_debug"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateVisible|adjustPan"
    android:theme="@style/EbpayThemeActivit"/>
<activity
    android:name="com.baidu.paysdk.ui.BindSmsActivity"
    android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    android:excludeFromRecents="true"
    android:screenOrientation="portrait"
    android:exported="@bool/bd_wallet_switch_global_debug"
    android:theme="@style/EbpayThemeActivit"
    android:windowSoftInputMode="adjustResize" />
<activity
    android:name="com.baidu.paysdk.ui.SelectBindCardActivity"
    android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    android:excludeFromRecents="true"
    android:exported="@bool/bd_wallet_switch_global_debug"
    android:screenOrientation="portrait"
    android:theme="@style/EbpayThemeActivit"
    android:windowSoftInputMode="stateHidden" />
<activity
    android:name="com.baidu.paysdk.ui.SecurityCenterActivity"
    android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    android:excludeFromRecents="true"
    android:exported="@bool/bd_wallet_switch_global_debug"
    android:screenOrientation="portrait"
    android:theme="@style/EbpayThemeActivit"
    android:windowSoftInputMode="adjustUnspecified|stateHidden" />
<activity
    android:name="com.baidu.paysdk.ui.PrivacyProtectionActivity"
    android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    android:excludeFromRecents="true"
    android:exported="@bool/bd_wallet_switch_global_debug"
    android:screenOrientation="portrait"
    android:theme="@style/EbpayThemeActivit"
    android:windowSoftInputMode="adjustUnspecified|stateHidden" />
<activity
    android:name="com.baidu.paysdk.ui.PhonePwdActivity"
    android:configChanges="keyboardHidden|navigation|orientation|screenSize"
    android:excludeFromRecents="true"
    android:exported="@bool/bd_wallet_switch_global_debug"
    android:theme="@style/EbpayThemeActivit"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="adjustUnspecified|stateHidden" /> sible" />

2.4 请求服务器,获得 Charge

我们需要向服务器发起请求,来获得json类型的Charge。然后用获取到的Charge去请求pay。

参数是json格式的 String channel 和 int amount。channel即支付方式,amount即支付金额。

charge信息如下:

{
  "id": "ch_iPu9qTHSOy1GP88eX1X9afXD",
  "object": "charge",
  "created": 1464687715,
  "livemode": false,
  "paid": false,
  "refunded": false,
  "app": "app_1Gqj58ynP0mHeX1q",
  "channel": "alipay",
  "order_no": "403c6f0a48a25661",
  "client_ip": "101.81.25.208",
  "amount": 1,
  "amount_settle": 1,
  "currency": "cny",
  "subject": "Your Subject",
  "body": "Your Body",
  "extra": {},
  "time_paid": null,
  "time_expire": 1464774115,
  "time_settle": null,
  "transaction_no": null,
  "refunds": {
               "object": "list",
               "url": "\/v1\/charges\/ch_iPu9qTHSOy1GP88eX1X9afXD\/refunds",
               "has_more": false,
               "data": []
             },
  "amount_refunded": 0,
  "failure_code": null,
  "failure_msg": null,
  "metadata": {},
  "credential": {
  					"object": "credential",
  					"alipay": {
              					"orderInfo": "_input_charset=\"utf-8\"&body=\"Your Body\"&it_b_pay=\"2016-06-01 17:41:55\"&notify_url=\"https%3A%2F%2Fapi.pingxx.com%2Fnotify%2Fcharges%2Fch_iPu9qTHSOy1GP88eX1X9afXD\"&out_trade_no=\"403c6f0a48a25661\"&partner=\"2008476488964232\"&payment_type=\"1\"&seller_id=\"2008476488964232\"&service=\"mobile.securitypay.pay\"&subject=\"Your Subject\"&total_fee=\"0.01\"&sign=\"eVhmMUtLRHViSENTemZUdVAwS0dDYWpM\"&sign_type=\"RSA\""
            					}
  				},
  "description": null
  }

其实,支付最核心的代码是:

Intent intent = new Intent(MainActivity.this, PaymentActivity.class);
intent.putExtra(PaymentActivity.EXTRA_CHARGE, data);
startActivityForResult(intent, REQUEST_CODE_PAYMENT);

Pingpp类的createPayment()方法封装了上述代码,所以下面的例子中和我们直接用这行代码来发起支付请求。

Pingpp.createPayment(ClientSDKActivity.this, data);

注意:

  1. manifest文件中PaymentActivity必须注册。
  2. 另外,需要接入哪种支付方式,就在manifest文件中注册对应的activity。
  3. wx 渠道是通过向微信客户端发起请求进行支付的,要求: 手机必须安装微信。 应用包名和签名必须与填写在微信开放平台上的一致,微信平台上的签名需是 MD5 且不带冒号的格式。 调试的时候必须打包出来测试,否则无法调用微信支付控件。

ClientSDKActivity即当前activity,data即我们从服务器获取到的Charge。

注意:

  1. 因为是向服务器请求数据,所以要用AsyncTask或者Thread+Handler

  2. 为了测试方便,我们新建一个ClientSDKActivity,包括记录输入金额的EditText,几个button,分别表示支付宝,微信支付等等。

以支付宝支付为例:

输入金额,点击“支付宝”支付按钮,向服务器发起请求。这里因为篇幅限制,我们只列出一些核心代码,具体的大家看源码。

/**
 * 支付支付渠道
 */
private static final String CHANNEL_ALIPAY = "alipay";

//官方给的获取chage的地址,用来模拟服务器
public static final String URL = "http://218.244.151.190/demo/charge";

@Override
public void onClick(View view) {
	//支付金额
    int amount = 0.01;

    // 点击“支付宝”按钮
    if (view.getId() == R.id.upmpButton) {
        new PaymentTask().execute(new PaymentRequest(CHANNEL_UPACP, amount));
    }
} 

class PaymentRequest {
	//支付方式
    String channel;
    //支付金额
    int amount;

    public PaymentRequest(String channel, int amount) {
        this.channel = channel;
        this.amount = amount;
    }
}

class PaymentTask extends AsyncTask<PaymentRequest, Void, String> {

    @Override
    protected void onPreExecute() {
        //按键点击之后的禁用,防止重复点击
        alipayButton.setOnClickListener(null);
    }

    @Override
    protected String doInBackground(PaymentRequest... pr) {

        PaymentRequest paymentRequest = pr[0];
        String data = null;
        String json = new Gson().toJson(paymentRequest);
        try {
            //向服务请求数据,这里做模拟,url是ping++官方给的测试url,能得到data
            //这里的data就是最后我们要拿去请求支付的参数。
            data = postJson(URL, json);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * 获得服务端的charge,调用ping++ sdk。
     */
    @Override
    protected void onPostExecute(String data) {
    	Log.d("charge", data);
    	//发起支付请求,需要在 onActivityResult 中处理支付返回信息
        Pingpp.createPayment(ClientSDKActivity.this, data);
    }

}

/**
 * onActivityResult 获得支付结果,如果支付成功,服务器会收到ping++ 服务器发送的异步通知。
 * 最终支付成功根据异步通知为准
 */
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 

    alipayButton.setOnClickListener(ClientSDKActivity.this);

    //支付页面返回处理
    if (requestCode == Pingpp.REQUEST_CODE_PAYMENT) {
        if (resultCode == Activity.RESULT_OK) {
            String result = data.getExtras().getString("pay_result");
            /* 处理返回值
             * "success" - payment succeed
             * "fail"    - payment failed
             * "cancel"  - user canceld
             * "invalid" - payment plugin not installed
             */
        }
    }
}

2.5 混淆设置

用户进行 apk 混淆打包的时候,为了不影响 Ping++ SDK 以及渠道 SDK 的使用,请在 proguard-rules 中添加一下混淆规则。

-dontwarn com.alipay.**
-keep class com.alipay.** {*;}

-dontwarn  com.ta.utdid2.**
-keep class com.ta.utdid2.** {*;}

-dontwarn  com.ut.device.**
-keep class com.ut.device.** {*;}

-dontwarn  com.tencent.**
-keep class com.tencent.** {*;}

-dontwarn  com.unionpay.**
-keep class com.unionpay.** {*;}

-dontwarn com.pingplusplus.**
-keep class com.pingplusplus.** {*;}

-dontwarn com.baidu.**
-keep class com.baidu.** {*;}

-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}

3. 其他

好了,支付基本的使用我们已经讲完了,live模式这里就不多说了,大家自己去查阅官方文档。红包的使用需要serer端发起,所以暂时不讲,放到后面。

  1. 微信现金红包、企业转帐、支付宝扫码和微信公众帐号扫码支付的支付流程比较类似,都只需要 Server 端发起请求即可。

  2. 现金红包红包使用的是 Red Envelopde 对象,企业转帐使用的是 Transfer 对象,而其他的都是使用的 Charge 对象。

参考:

pin++ github地址

ping++官方文档

转载于:https://my.oschina.net/u/2421076/blog/685190

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值