最近公司又又又接了一个新的需求,某银行和我们合作,银行的开发团队是外包性质,为了方便开发,需求方让我们提供一个微信,支付宝sdk,Native和hTMl的对接形式,顾写了如下:
本SDK不生成订单数据,完全模拟工作中正常交互
1.[SDK中build.gradle]引用微信支付宝JAR包
compile files('libs/wechat-sdk-android-with-mta-1.0.2.jar')//微信支付
compile files('libs/alipaySdk-20180601.jar')//支付宝支付
2.在[SDK中]ANDROIDMAINFEST.XML中添加权限以及微信支持
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="SDK包名">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true">
<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=".wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="${WEATCH_APPID}" />
</intent-filter>
</activity>-->
<!--<meta-data android:name="WEATCG_APPID" android:value="${WEATCH_APPID}"/>-->
</application>
</manifest>
3.[SDK]创建一个枚举
package 包名.bean;
/**
* @author fuqinming
*
* 支付类型枚举
*/
public enum PayType {
WEATCH_PAY ( "WEATCH_PAY" ), ALIAPY ( "ALIPAY" );
private String name;
// 构造方法
private PayType(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
4.[SDK]微信支付宝支付公共返回Model
package 包名.bean;
/**
* @author fuqinming
*
* 支付返回处理
*/
public class PayResult {
private int resultStatus;//支付返回状态
private String msg;//信息
private String sub_msg;//信息补充
private PayType type;//类型
public void setResultStatus(int resultStatus) {
this.resultStatus = resultStatus;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void setSub_msg(String sub_msg) {
this.sub_msg = sub_msg;
}
public int getResultStatus() {
return resultStatus;
}
public String getMsg() {
return msg;
}
public void setType(PayType type) {
this.type = type;
}
public String getSub_msg() {
return sub_msg;
}
public PayType getType() {
return type;
}
}
5.[SDK]创建微信支付订单Model
package 包名bean;
/*微信分享bean*/
public class WeachPayBeanVo{
//微信开放平台审核通过的应用APPID
private String appid;
//随机字符串,不长于32位。推荐随机数生成算法
private String noncestr;
//扩展字段[package]
private String packageValue;
//签名
private String sign;
//商户号
private String partnerid;
//预支付交易会话ID
private String prepayid;
//时间戳
private String timestamp;
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getNoncestr() {
return noncestr;
}
public void setNoncestr(String noncestr) {
this.noncestr = noncestr;
}
public String getPackageValue() {
return packageValue;
}
public void setPackageValue(String packageValue) {
this.packageValue = packageValue;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getPartnerid() {
return partnerid;
}
public void setPartnerid(String partnerid) {
this.partnerid = partnerid;
}
public String getPrepayid() {
return prepayid;
}
public void setPrepayid(String prepayid) {
this.prepayid = prepayid;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
@Override
public String toString() {
return "{\"appid\":\""+appid+"\",\"noncestr\":\""+noncestr+"\",\"package\":\""+packageValue+"\",\"sign\":\""+sign+"\",\"partnerid\":\""+partnerid+"\",\"prepayid\":\""+prepayid+"\",\"timestamp\":\""+timestamp+"\"}";
}
}
6.[SDK]支付帮助类
其实没多大用处,可能和自己刚开始的想法有关系,后面SDK导出的时候,忘记把他删除了,看各位需求吧,csdn排版一直是个心病,表示排版好难,有强迫症的我,还在研究如何好看
package 包名.utils;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import java.util.List;
/*支付帮助类*/
public class PayUtils {
/*获取当前运行的activity名称*/
public static String getRunningActivityName(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService ( Context.ACTIVITY_SERVICE );
String runningActivity = activityManager.getRunningTasks ( 1 ).get ( 0 ).topActivity.getClassName ();
String contextActivity = runningActivity.substring ( runningActivity.lastIndexOf ( "." ) + 1 );
return contextActivity;
}
/*获取当前运行的报名*/
public static String getAppPackageName(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService ( Context.ACTIVITY_SERVICE );
List <ActivityManager.RunningTaskInfo> taskInfo = activityManager.getRunningTasks ( 1 );
ComponentName componentInfo = taskInfo.get ( 0 ).topActivity;
return componentInfo.getPackageName ();
}
/*判空*/
public static boolean isEmpty(String str) {
return null == str || "".equals(str.trim()) || "null".equals(str.trim());
}
}
6.[SDK]微信支付宝支付原生提供给HTML js 支持 类
package 包名.utils;
import android.app.Activity;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.widget.Toast;
import com.google.gson.Gson;
import 包名.R;
import 包名.bean.WeachPayBeanVo;
/**
* @author fuqinming
*
* 提供给html对接的支付function js类
*/
public class ReachDoolyPlugin{
private static final String TAG = "ReachDoolyPlugin";
public static final String NAME = "js注册名称";//js注册名称
private Activity activity;//传入activity
private WebView webView;//webview
ReachDoolyPlugin(Activity activity, WebView webView) {
this.activity = activity;
this.webView = webView;
}
@JavascriptInterface
public void wechatPay(final String json, final String func) {
Log.i (TAG,"wechatPay()----------->");
if(activity instanceof WeatchPayBaseActivity) {
activity.runOnUiThread ( new Runnable () {
@Override
public void run() {
String jsonParams = json;
if (!PayUtils.isEmpty ( jsonParams ) && !PayUtils.isEmpty ( func )) {
jsonParams = jsonParams.replace ( "\"package\"", "\"packageValue\"" );
WeachPayBeanVo weachPayVo = new WeachPayBeanVo ();
try {
weachPayVo = new Gson ().fromJson ( jsonParams, WeachPayBeanVo.class );
} catch (Exception e) {
weachPayVo = null;
}
if (weachPayVo != null && !PayUtils.isEmpty ( weachPayVo.getAppid () ) &&
!PayUtils.isEmpty ( weachPayVo.getNoncestr () ) && !PayUtils.isEmpty ( weachPayVo.getPackageValue () )
&& !PayUtils.isEmpty ( weachPayVo.getPartnerid () ) && !PayUtils.isEmpty ( weachPayVo.getPrepayid () ) &&
!PayUtils.isEmpty ( weachPayVo.getSign () ) && !PayUtils.isEmpty ( weachPayVo.getTimestamp () )) {
((WeatchPayBaseActivity)activity).wechatPay (weachPayVo, func );
} else {
Toast.makeText ( activity, activity.getResources ().getString ( R.string.error_order_msg ), Toast.LENGTH_SHORT );
}
}
}
} );
}
}
/*阿里支付*/
@JavascriptInterface
public void aliPay(final String json,final String func){
Log.i (TAG,"aliPay()----------->");
if(activity instanceof WeatchPayBaseActivity) {
activity.runOnUiThread ( new Runnable () {
@Override
public void run() {
String jsonParams = json;
if (!PayUtils.isEmpty ( jsonParams ) && !PayUtils.isEmpty ( func )) {
(( WeatchPayBaseActivity)activity).aliPay ( json, func );
}
}
} );
}
}
}
7.[SDK]父Activity
package 包名.utils;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.widget.Toast;
import com.alipay.sdk.app.PayTask;
import com.google.gson.Gson;
import 包名.R;
import 包名.bean.ALIPayResult;
import 包名.bean.PayResult;
import 包名.bean.PayType;
import 包名.bean.WeachPayBeanVo;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import java.util.Map;
/**
* @author fuqinming
* <p>
* 微信支付base类
*/
public class WeatchPayBaseActivity extends Activity implements IWXAPIEventHandler {
public IWXAPI api;//微信api
public PayReq payReq;//微信支付
public WeatchPayReceiver weatchPayReceiver;//微信支付回調
private String payCallBack = "";
private String aliPayCallBack="";//阿里支付返回
private WebView webView = null;
private static final int SDK_PAY_FLAG = 1001;//阿里支付调起返回
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate ( savedInstanceState );
initWXAPI ( this );
initWeatchPayReciver ();
}
/*初始化微信*/
private void initWXAPI(Activity context) {
String APP_ID = "";
try {
ApplicationInfo activityInfo = this.getPackageManager ().getApplicationInfo ( this.getPackageName (), PackageManager.GET_META_DATA );
APP_ID = activityInfo.metaData.getString ( "WEATCG_APPID" );
} catch (Exception e) {
APP_ID = "";
}
payReq = new PayReq ();
if (null == APP_ID || "".equals ( APP_ID.trim () ) || "null".equals ( APP_ID.trim () )) {
throw new NullPointerException ();
}
// 初始化分享
api = WXAPIFactory.createWXAPI ( context, APP_ID, true );
api.handleIntent ( context.getIntent (), this );
api.registerApp ( APP_ID );
}
/*注册广播*/
private void initWeatchPayReciver() {
weatchPayReceiver = new WeatchPayReceiver ();
IntentFilter intentFilter = new IntentFilter ();
intentFilter.addAction ( "WEACHATPAY" );
registerReceiver ( weatchPayReceiver, intentFilter );
}
@Override
public void onReq(BaseReq baseReq) {
}
/*添加支付html支持*/
public void addPayJavaScript(final Activity activity, WebView webView) {
if (webView != null) {
this.webView = webView;
ReachDoolyPlugin nativePlugin = new ReachDoolyPlugin ( activity, webView );
webView.addJavascriptInterface ( nativePlugin, "js注册名称" );
}
}
/*微信支付方法*/
public void wechatPay(WeachPayBeanVo weachPayVo) {
if (payReq != null && weachPayVo != null && !PayUtils.isEmpty ( weachPayVo.getAppid () ) && !PayUtils.isEmpty ( weachPayVo.getNoncestr () )
&& !PayUtils.isEmpty ( weachPayVo.getPackageValue () ) && !PayUtils.isEmpty ( weachPayVo.getPartnerid () )
&& !PayUtils.isEmpty ( weachPayVo.getPrepayid () ) && !PayUtils.isEmpty ( weachPayVo.getSign () )
&& !PayUtils.isEmpty ( weachPayVo.getTimestamp () )) {
this.payCallBack="";
payReq.appId = weachPayVo.getAppid ();
payReq.partnerId = weachPayVo.getPartnerid ();// 微信支付分配的商户号
payReq.prepayId = weachPayVo.getPrepayid ();// 微信返回的支付交易会话ID
payReq.packageValue = weachPayVo.getPackageValue ();// 扩展字段占时填固定
payReq.nonceStr = weachPayVo.getNoncestr ();// 随机字符串
payReq.timeStamp = weachPayVo.getTimestamp ();// 时间戳
payReq.sign = weachPayVo.getSign ();// 签名
api.sendReq ( payReq );
} else {
Toast.makeText ( this, getResources ().getString ( R.string.error_order_msg ), Toast.LENGTH_SHORT );
}
}
/*微信支付方法*/
public void wechatPay(WeachPayBeanVo weachPayVo, String funcName) {
this.payCallBack = funcName;
if (payReq != null && weachPayVo != null && !PayUtils.isEmpty ( weachPayVo.getAppid () ) && !PayUtils.isEmpty ( weachPayVo.getNoncestr () )
&& !PayUtils.isEmpty ( weachPayVo.getPackageValue () ) && !PayUtils.isEmpty ( weachPayVo.getPartnerid () )
&& !PayUtils.isEmpty ( weachPayVo.getPrepayid () ) && !PayUtils.isEmpty ( weachPayVo.getSign () )
&& !PayUtils.isEmpty ( weachPayVo.getTimestamp () )) {
payReq.appId = weachPayVo.getAppid ();
payReq.partnerId = weachPayVo.getPartnerid ();// 微信支付分配的商户号
payReq.prepayId = weachPayVo.getPrepayid ();// 微信返回的支付交易会话ID
payReq.packageValue = weachPayVo.getPackageValue ();// 扩展字段占时填固定
payReq.nonceStr = weachPayVo.getNoncestr ();// 随机字符串
payReq.timeStamp = weachPayVo.getTimestamp ();// 时间戳
payReq.sign = weachPayVo.getSign ();// 签名
api.sendReq ( payReq );
} else {
Toast.makeText ( this, getResources ().getString ( R.string.error_order_msg ), Toast.LENGTH_SHORT );
}
}
/*阿里支付*/
public void aliPay(final String orderInfo){
if(!PayUtils.isEmpty ( orderInfo )) {
this.aliPayCallBack="";
//异步处理
Runnable payRunnable = new Runnable () {
@Override
public void run() {
//新建任务
PayTask alipay = new PayTask ( WeatchPayBaseActivity.this );
//获取支付结果
Map <String, String> result = alipay.payV2 ( orderInfo, true );
Message msg = new Message ();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage ( msg );
}
};
// 必须异步调用
Thread payThread = new Thread ( payRunnable );
payThread.start ();
}
}
/*阿里支付*/
public void aliPay(final String orderInfo,String func){
if(!PayUtils.isEmpty ( orderInfo ) && !PayUtils.isEmpty ( func )) {
this.aliPayCallBack=func;
//异步处理
Runnable payRunnable = new Runnable () {
@Override
public void run() {
//新建任务
PayTask alipay = new PayTask ( WeatchPayBaseActivity.this );
//获取支付结果
Map <String, String> result = alipay.payV2 ( orderInfo, true );
Message msg = new Message ();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage ( msg );
}
};
// 必须异步调用
Thread payThread = new Thread ( payRunnable );
payThread.start ();
}
}
/*阿里支付异步*/
private Handler mHandler = new Handler () {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case SDK_PAY_FLAG:
ALIPayResult payResult = new ALIPayResult((Map<String, String>) msg.obj);
//同步获取结果
String resultInfo = payResult.getResult();
String resultStatus = payResult.getResultStatus();
if (!PayUtils.isEmpty ( aliPayCallBack ) && webView != null) {
webView.loadUrl ( "javascript:" + aliPayCallBack + "(" + resultStatus + ")" );
}else{
payCallBackFunction (getALiRayResult ( payResult ));
}
break;
}
}
};
/*第三方应用发送到微信的请求处理后的响应结果,会回调到该方法*/
public void onResp(BaseResp resp) {
}
/*支付返回广播*/
public class WeatchPayReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
//只有一个bundle的消息,用intent.getStringExtra(key)取值就行
if (intent != null && !PayUtils.isEmpty ( intent.getAction () ) && intent.getAction ().equals ( "WEACHATPAY" )) {
int errCode = -5;
try {
errCode = Integer.parseInt ( intent.getStringExtra ( "errCode" ) );
} catch (Exception e) {
errCode = -5;
}
if (!PayUtils.isEmpty ( payCallBack ) && webView != null) {
webView.loadUrl ( "javascript:" + payCallBack + "(" + errCode + ")" );
} else {
payCallBackFunction ( getWechatPayResult ( errCode ) );
}
}
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, final Intent data) {
super.onActivityResult ( requestCode, resultCode, data );
/*微信支付回调*/
if (resultCode == 101 && data != null && !PayUtils.isEmpty ( data.getStringExtra ( "errCode" ) )) {
int errCode = -5;
try {
errCode = Integer.getInteger ( data.getStringExtra ( "errCode" ) );
} catch (Exception e) {
errCode = -5;
}
final int errCodeInt = errCode;
this.runOnUiThread ( new Runnable () {
@Override
public void run() {
if (!PayUtils.isEmpty ( payCallBack ) && webView != null) {
webView.loadUrl ( "javascript:" + payCallBack + "(" + errCodeInt + ")" );
} else {
payCallBackFunction ( getWechatPayResult ( errCodeInt ));
}
}
} );
}
}
/*阿里支付返回*/
public void payCallBackFunction(PayResult aliPay){
}
@Override
protected void onDestroy() {
super.onDestroy ();
payCallBack = "";
aliPayCallBack="";
/*注销广播事件*/
if (weatchPayReceiver != null) {
unregisterReceiver ( weatchPayReceiver );
}
}
private PayResult getALiRayResult(ALIPayResult payResult){
PayResult resultPay=new PayResult ();
resultPay.setType ( PayType.ALIAPY );
String resultStatus=payResult.getResultStatus ();
if(resultStatus.equals ( "9000" )){
resultPay.setResultStatus ( 0 );
resultPay.setMsg ( "支付成功" );
}else if(resultStatus.equals ( "6001" )){
resultPay.setResultStatus ( -2 );
resultPay.setMsg ( "用户中途取消" );
}else if(resultStatus.equals ( "8000" )){
resultPay.setResultStatus ( 1 );
resultPay.setMsg ( "正在处理中,支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态" );
}else{
resultPay.setResultStatus ( -1 );
resultPay.setMsg ( "订单支付失败" );
resultPay.setSub_msg ( payResult.getResult () );
}
return resultPay;
}
/*微信支付状态返回*/
private PayResult getWechatPayResult(int errCode){
PayResult resultPay=new PayResult ();
resultPay.setResultStatus ( errCode );
resultPay.setType ( PayType.WEATCH_PAY );
if(errCode==0){
resultPay.setMsg ( "支付成功" );
}else if(errCode==-1){
resultPay.setMsg ( "支付失败" );
resultPay.setSub_msg ( "可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。" );
}else if(errCode==-2){
resultPay.setMsg ( "用户中途取消" );
}else{
resultPay.setResultStatus (-2);
resultPay.setMsg ( "支付失败" );
resultPay.setSub_msg ( "其他错误" );
}
return resultPay;
}
}
8.[SDK]String.xml错误信息配置
<resources>
<string name="error_order_msg">订单异常,不可进行支付</string>
</resources>
9.[SDK]微信支付必须文件
package 包名.wxapi;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.Window;
import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
/**
* 微信支付回调部分
* 微信要求必须有该类
*/
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
private IWXAPI api;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate ( savedInstanceState );
requestWindowFeature ( Window.FEATURE_NO_TITLE );
String APP_ID = "";
try {
ApplicationInfo activityInfo = this.getPackageManager ().getApplicationInfo ( this.getPackageName (), PackageManager.GET_META_DATA );
APP_ID = activityInfo.metaData.getString ( "WEATCG_APPID" );
} catch (Exception e) {
}
if (null == APP_ID || "".equals ( APP_ID.trim () ) || "null".equals ( APP_ID.trim () )) {
NullPointerException nullError = new NullPointerException ( "WEACH_APPID Value is not set, params is null" );
throw nullError;
}
api = WXAPIFactory.createWXAPI ( this, APP_ID );
api.handleIntent ( getIntent (), this );
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent ( intent );
setIntent ( intent );
api.handleIntent ( intent, this );
}
@Override
public void onReq(BaseReq req) {
}
@Override
public void onResp(BaseResp resp) {
//支付
if (resp.getType () == ConstantsAPI.COMMAND_PAY_BY_WX) {
int errCode = resp.errCode;
Intent intent = new Intent ();
intent.setAction ( "WEACHATPAY" );
intent.putExtra ( "errCode", errCode + "" );
sendBroadcast ( intent );
WXPayEntryActivity.this.finish ();
}
}
}
二.下面为DEMO使用SDK
1.[DEMO]写几个布局xml文件
1)layout_main.xml布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/person_top_lin"
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="#ffffff"
android:orientation="horizontal">
<TextView
android:id="@+id/tvTopTextTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:ellipsize="end"
android:lines="1"
android:maxEms="8"
android:text="支付测试"
android:textSize="18sp"
android:visibility="visible" />
</RelativeLayout>
<View
android:layout_width="fill_parent"
android:layout_height="1px"
android:background="#f5f5f5" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="20dp"
android:paddingRight="20dp">
<Button
android:id="@+id/native_pay"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_marginTop="20dp"
android:background="@drawable/abc_ab_stacked_transparent_light_holo"
android:gravity="center"
android:text="原生调起支付"
android:textColor="#161616"
android:textSize="20sp" />
<Button
android:id="@+id/html_pay"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_marginTop="20dp"
android:background="@drawable/abc_ab_stacked_transparent_light_holo"
android:gravity="center"
android:text="HTML调起支付"
android:textSize="20sp" />
<View
android:layout_width="fill_parent"
android:layout_height="20dp" />
</LinearLayout>
</ScrollView>
</LinearLayout>
2)pay_native_layout.xml[自己调用自己布局]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="#ffffff"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:ellipsize="end"
android:lines="1"
android:maxEms="8"
android:text="NATIVE调起支付"
android:textSize="18sp"
android:visibility="visible" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:paddingLeft="15dp"
android:paddingRight="3dp"
android:onClick="goback"
android:gravity="center"
android:visibility="visible">
<ImageView
android:id="@+id/comm_top_back_img"
android:layout_width="8dp"
android:layout_height="15dp"
android:layout_marginLeft="1dp"
android:background="@drawable/arrow_left" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="14dp"
android:text=""
android:layout_toRightOf="@+id/comm_top_back_img"
android:textColor="#333333"
android:textSize="14sp"
android:visibility="invisible" />
</RelativeLayout>
</RelativeLayout>
<View
android:layout_width="fill_parent"
android:layout_height="1px"
android:background="#f5f5f5" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="20dp"
android:paddingRight="20dp">
<Button
android:id="@+id/weatch_pay"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_marginTop="20dp"
android:background="@drawable/abc_ab_stacked_transparent_light_holo"
android:gravity="center"
android:onClick="weatchPay"
android:text="微信支付"
android:textColor="#161616"
android:textSize="20sp" />
<Button
android:id="@+id/ali_pay"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_marginTop="20dp"
android:background="@drawable/abc_ab_stacked_transparent_light_holo"
android:gravity="center"
android:text="支付宝支付"
android:onClick="aliPay"
android:textSize="20sp" />
<View
android:layout_width="fill_parent"
android:layout_height="20dp" />
</LinearLayout>
</ScrollView>
</LinearLayout>
3)pay_web_layout.xml[html调用原生布局]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="#ffffff"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:ellipsize="end"
android:lines="1"
android:maxEms="8"
android:text="HTML调起原生支付"
android:textSize="18sp"
android:visibility="visible" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:paddingLeft="15dp"
android:paddingRight="3dp"
android:gravity="center"
android:onClick="goback"
android:visibility="visible">
<ImageView
android:id="@+id/comm_top_back_img"
android:layout_width="8dp"
android:layout_height="15dp"
android:layout_marginLeft="1dp"
android:background="@drawable/arrow_left" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="14dp"
android:text=""
android:layout_toRightOf="@+id/comm_top_back_img"
android:textColor="#333333"
android:textSize="14sp"
android:visibility="invisible" />
</RelativeLayout>
</RelativeLayout>
<View
android:layout_width="fill_parent"
android:layout_height="1px"
android:background="#f5f5f5" />
<WebView
android:id="@+id/view_webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff" />
</LinearLayout>
4)assets/index.html[模拟html调用原生]
<html>
<head>
<title>HTML调起原生支付</title>
<style type="text/css">
body{
margin:20px;
}
input{
width:200px;
height:50px;
background:#f2f2f2;
color:#161616;
border:0;
outline:none;
border-radius:6px;
font-size:18px;
}
</style>
<script type="text/javascript">
function weatchPay(){
var json="{\"appid\":\"wx166312d102c5d680\",\"noncestr\":\"ade55409d1224074754035a5a937d2e0\",\"packageValue\":\"Sign=WXPay\",\"partnerid\":\"1489993422\",\"prepayid\":\"wx1516414346268735be1104e93980871271\",\"sign\":\"81BE92ED61E2E221BE5D3028E4E15AD3\",\"timestamp\":\"1529052103\"}";
js注册名称.wechatPay(json,"weatchPayResult");
}
function aliPay(){
var json= "biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%220621105451-1654%22%7D&method=alipay.trade.app.pay&charset=utf-8&version=1.0&app_id=2017062807585767×tamp=2016-07-29+16%3A55%3A53&sign_type=RSA&sign=LDfqg4VYEMxz0dtqy8SxNglfVDEync%2FeKSNByxxzpWU6e8w0cu7E6h4A%2B0uXQs31gAK%2Bp0KdwWwX7PYix%2BINPWujuMiQehsZQlS5L1t0QwhNp4vu8PYMYIdt6IVqTHxR3NxK3kp%2FZspJ0om3fAjV5hFvHgR%2BBcjQywqWBjmkeDiLJLhQDoujREq27veIqyCBGQ16a81FBDS2Hv1EiO4INjnE%2Ff3vBxXrUfYx2vBxQv9wwiqDg%2FOrxlG1a9SoFjC%2BnxnCFVkFQdSw4Z5ftMy7lDQFh2VyuzxTN2D%2FYgH%2B3cTIMzCiF7vTkfbBVIPmXarb6o8%2BJhVNGnxcjb0t9N2C9g%3D%3D";
js注册名称.aliPay(json,"aliPayResult");
}
function weatchPayResult(dd){
//微信支付回掉,一般为html自己拉取订单状态,也可以使用传参状态
if(dd==0){
alert("微信支付成功");
}else if(dd==-1){
alert("微信支付失败");
}else if(dd==-2){
alert("用户取消微信支付");
}else{
alert("其他微信支付错误");
}
}
function aliPayResult(dd){
if(dd==0){
alert("支付宝支付成功");
}else if(dd==-1){
alert("支付宝支付失败");
}else if(dd==-2){
alert("用户取消支付宝支付");
}else{
alert("其他支付宝支付错误");
}
}
</script>
</head>
<body>
下面为HTML调用原生支付测试:
<p/>
<input type="submit" value="微信支付" onclick="weatchPay()"/>
<p/>
<input type="submit" value="支付宝支付" onclick="aliPay()"/>
</body>
</html>
2.[DEMO]拷贝微信需要信息到DEMO,SDK可以不遗留相关信息
使用支付sdk
在setting.gradle
include ‘:app’,’:SDK名字’
1)class类
package DEMO包名.wxapi;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.Window;
import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
/**
* 微信支付回调部分
* 微信要求必须有该类
*/
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
private IWXAPI api;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate ( savedInstanceState );
requestWindowFeature ( Window.FEATURE_NO_TITLE );
String APP_ID = "";
try {
ApplicationInfo activityInfo = this.getPackageManager ().getApplicationInfo ( this.getPackageName (), PackageManager.GET_META_DATA );
APP_ID = activityInfo.metaData.getString ( "WEATCG_APPID" );
} catch (Exception e) {
}
if (null == APP_ID || "".equals ( APP_ID.trim () ) || "null".equals ( APP_ID.trim () )) {
NullPointerException nullError = new NullPointerException ( "WEACH_APPID Value is not set, params is null" );
throw nullError;
}
api = WXAPIFactory.createWXAPI ( this, APP_ID );
api.handleIntent ( getIntent (), this );
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent ( intent );
setIntent ( intent );
api.handleIntent ( intent, this );
}
@Override
public void onReq(BaseReq req) {
}
@Override
public void onResp(BaseResp resp) {
//支付
if (resp.getType () == ConstantsAPI.COMMAND_PAY_BY_WX) {
int errCode = resp.errCode;
Intent intent = new Intent ();
intent.setAction ( "WEACHATPAY" );
intent.putExtra ( "errCode", errCode + "" );
sendBroadcast ( intent );
WXPayEntryActivity.this.finish ();
}
}
}
2)androidMainFest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="DEMO包名">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- 支付回调页面 -->
<activity
android:name=".wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="${WEATCH_APPID}" />
</intent-filter>
</activity>
<meta-data android:name="WEATCG_APPID" android:value="${WEATCH_APPID}"/>
</application>
</manifest>
3)build.gradle
apply plugin: 'com.android.application'
android {
signingConfigs {
debug {
}
}
compileSdkVersion 18
buildToolsVersion '27.0.2'
defaultConfig {
applicationId "demo包名"
minSdkVersion 20
targetSdkVersion 18
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
manifestPlaceholders = [
"WEATCH_APPID": "xxxxxxxxxxx",//加入自己的微信支付appid
]
}
buildTypes {
debug {
signingConfig signingConfigs.debug
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation 'com.android.support:appcompat-v7:18.0.0'
implementation project(':sdk名称')
}
一切搞定,下面只需要调用即可
3.[DEMO]微信支付宝支付调用
1)PayTestActivity
package DEMO包名;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
/**
*@author fuqinming
*
* 支付测试
*/
public class PayTestActivity extends Activity implements View.OnClickListener{
private Button nativePay;
private Button htmlPay;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate ( savedInstanceState );
setContentView ( R.layout.layout_main );
initView ();
initActive ();
}
private void initView(){
nativePay=(Button)findViewById ( R.id.native_pay );
htmlPay=(Button)findViewById ( R.id.html_pay );
}
private void initActive(){
nativePay.setOnClickListener ( this );
htmlPay.setOnClickListener ( this );
}
@Override
public void onClick(View v) {
switch (v.getId ()){
case R.id.native_pay://
startActivity (new Intent ( PayTestActivity.this, PayNativeTestActivity.class ) );
break;
case R.id.html_pay:
startActivity (new Intent ( PayTestActivity.this, PayWebActivity.class ) );
break;
}
}
}
2)PayNativeTestActivity[自己调用自己]
package DEMO包名;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.google.gson.Gson;
import SDK包名.bean.PayResult;
import SDK包名.bean.PayType;
import SDK包名.bean.WeachPayBeanVo;
import SDK包名.utils.WeatchPayBaseActivity;
/**
* @author fuqinming
* <p>
* 原生调用自己支付
*/
public class PayNativeTestActivity extends WeatchPayBaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate ( savedInstanceState );
setContentView ( R.layout.pay_native_layout );
}
/*微信支付[来源view onclick]*/
public void weatchPay(View view) {
String str = "{\"appid\":\"wx166312d102c5d680\",\"noncestr\":\"ade55409d1224074754035a5a937d2e0\",\"packageValue\":\"Sign=WXPay\",\"partnerid\":\"1489993422\",\"prepayid\":\"wx1516414346268735be1104e93980871271\",\"sign\":\"81BE92ED61E2E221BE5D3028E4E15AD3\",\"timestamp\":\"1529052103\"}";
WeachPayBeanVo data = new Gson ().fromJson ( str, WeachPayBeanVo.class );
wechatPay ( data );//微信支付
}
/*阿里支付[来源view onclick]*/
public void aliPay(View view) {
String order_str = "biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%220621105451-1654%22%7D&method=alipay.trade.app.pay&charset=utf-8&version=1.0&app_id=2017062807585767×tamp=2016-07-29+16%3A55%3A53&sign_type=RSA&sign=LDfqg4VYEMxz0dtqy8SxNglfVDEync%2FeKSNByxxzpWU6e8w0cu7E6h4A%2B0uXQs31gAK%2Bp0KdwWwX7PYix%2BINPWujuMiQehsZQlS5L1t0QwhNp4vu8PYMYIdt6IVqTHxR3NxK3kp%2FZspJ0om3fAjV5hFvHgR%2BBcjQywqWBjmkeDiLJLhQDoujREq27veIqyCBGQ16a81FBDS2Hv1EiO4INjnE%2Ff3vBxXrUfYx2vBxQv9wwiqDg%2FOrxlG1a9SoFjC%2BnxnCFVkFQdSw4Z5ftMy7lDQFh2VyuzxTN2D%2FYgH%2B3cTIMzCiF7vTkfbBVIPmXarb6o8%2BJhVNGnxcjb0t9N2C9g%3D%3D";
aliPay ( order_str );//阿里支付
}
/*支付回调*/
public void payCallBackFunction(PayResult payResult) {
super.payCallBackFunction ( payResult );
PayType payType=payResult.getType ();
String type=payType.getName ();
if (payResult.getResultStatus () == 0) {
Toast.makeText ( this, type+"支付成功", Toast.LENGTH_LONG ).show ();
} else if (payResult.getResultStatus () == -1) {
Toast.makeText ( this, type+"支付失败", Toast.LENGTH_LONG ).show ();
} else if (payResult.getResultStatus () == -2) {
Toast.makeText ( this, type+"用户取消", Toast.LENGTH_LONG ).show ();
} else {
Toast.makeText ( this, type+"未知错误,请检查环境配置", Toast.LENGTH_LONG ).show ();
}
}
public void goback(View view){
this.finish ();
}
}
3)PayWebActivity[webview中html调用原生支付]
package DEMO包名
import android.os.Bundle;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import SDK包名.utils.WeatchPayBaseActivity;
/**
* @author fuqinming
*
* html调用native支付
*/
public class PayWebActivity extends WeatchPayBaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate ( savedInstanceState );
setContentView ( R.layout.pay_web_layout );
WebView viewView=(WebView)findViewById ( R.id.view_webview );
viewView.getSettings ().setJavaScriptEnabled ( true );
addPayJavaScript(this,viewView);//添加webview支付支持
String url="file:///android_asset/index.html";
viewView.setWebChromeClient(new WebChromeClient ());//必须有这句话,否则html弹框无效
viewView.loadUrl ( url );
}
public void goback(View view){
this.finish ();
}
}
这个需求就完成了,自己累记下,也方便后期自己开发