项目中部分功能点需要用到支付功能,移动端主要集成支付宝支付和微信支付
支付宝sdk以及demo下载地址:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.JuZcSc&treeId=54&articleId=104509&docType=1
微信sdk以及demo下载地址:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1
支付宝支付最简单,而且文档,demo都有利于开发者阅读
微信支付集成和demo是最烂的
微信支付和支付宝支付封装基类,封装支付宝相关回调,和支付调用操作,以及微信调用操作:
import android.annotation.TargetApi; import android.app.Dialog; import android.content.res.Resources; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; import com.alipay.sdk.app.PayTask; import com.utils.logger.util.Logger; import com.pay.library.alipay.PayResult; import com.tencent.mm.sdk.modelpay.PayReq; import com.tencent.mm.sdk.openapi.IWXAPI; import com.tencent.mm.sdk.openapi.WXAPIFactory; @TargetApi(Build.VERSION_CODES.HONEYCOMB) public abstract class BasePayActivity extends BaseFragmentActivity implements OnClickListener { private final static int DIALOG_PROGRESS = 1; protected String TAG = "soyoungboy"; protected Resources res; // private ProgressDialog progressDialog; private Dialog progressDialog; private static final int SDK_PAY_FLAG = 1; private Handler mHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case SDK_PAY_FLAG: { PayResult payResult = new PayResult((String) msg.obj); /** * 同步返回的结果必须放置到服务端进行验证(验证的规则请看https://doc.open.alipay.com/doc2/ * detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665& * docType=1) 建议商户依赖异步通知 */ String resultInfo = payResult.getResult();// 同步返回需要验证的信息 String resultStatus = payResult.getResultStatus(); // 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档 if (TextUtils.equals(resultStatus, "9000")) { alipaySuccess(payResult); } else { // 判断resultStatus 为非"9000"则代表可能支付失败 // "8000"代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态) if (TextUtils.equals(resultStatus, "8000")) { alipayConfirm(payResult); } else { Logger.i(payResult.toString()); // 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误 alipayFail(payResult); } } break; } //case SDK_CHECK_FLAG: { // Toast.makeText(PayDemoActivity.this, "检查结果为:" + msg.obj, Toast.LENGTH_SHORT).show(); // break; //} default: break; } } }; @Override protected void onCreate(Bundle arg0) { super.onCreate(arg0); } /** * @Description: 初始化顶部TitleView * @return:void */ protected abstract void initTitleView(); /** * @Description: 初始化UI(setContentView放在initView) * @return:void */ protected abstract void initView(); /** * @Description: 点击事件 * @return:void */ protected abstract void click(View view); /** * 支付宝支付 * * @param payInfo 服务器端返回的订单信息 */ protected void alipay(final String payInfo) { Runnable payRunnable = new Runnable() { @Override public void run() { // 构造PayTask 对象 PayTask alipay = new PayTask(BasePayActivity.this); // 调用支付接口,获取支付结果 String result = alipay.pay(payInfo, true); Message msg = new Message(); msg.what = SDK_PAY_FLAG; msg.obj = result; mHandler.sendMessage(msg); } }; // 必须异步调用 Thread payThread = new Thread(payRunnable); payThread.start(); } /** * 支付结果确认中 * @param payResult */ protected abstract void alipayConfirm(PayResult payResult); /** * 支付结果失败 * @param payResult */ protected abstract void alipayFail(PayResult payResult); /** * 支付结果成功 * @param payResult */ protected abstract void alipaySuccess(PayResult payResult); /** * 微信支付 * https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_12&index=2 * * @param appid 微信分配的公众账号ID * @param partnerid 微信支付分配的商户号 * @param prepayid 微信返回的支付交易会话ID * @param noncestr 随机字符串,不长于32位。推荐随机数生成算法 https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=4_3 * @param timestamp 时间戳,请见接口规则-参数规定 https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=4_2 * @param packageX 暂填写固定值Sign=WXPay * @param sign 签名,详见签名生成算法 * @param extData 额外的标记,未知 */ protected void wechatPay(String appid, String partnerid, String prepayid, String noncestr, String timestamp, String packageX, String sign, String extData) { IWXAPI api = WXAPIFactory.createWXAPI(BasePayActivity.this, appid); PayReq req = new PayReq(); req.appId = appid; req.partnerId = partnerid; req.prepayId = prepayid; req.nonceStr = noncestr; req.timeStamp = timestamp; req.packageValue = packageX; req.sign = sign; req.extData = extData; // 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信 api.sendReq(req); } }
支付宝支付调用:
继承自上面这个类,代码里面如下调用:
pay_data为服务器端帮你处理后的订单信息。
String pay_data = data.getPay_data();
alipay(pay_data);
实现上面的抽象方法,即可处理支付宝成功,失败,确认中的操作来进行支付后的下一步操作。
微信支付调用:
weChatPayResult = Json.get() .toObject(response, WeChatPayResult.class); WeChatPayResult.DataEntity data = weChatPayResult.getData(); WeChatPayResult.DataEntity.PayDataEntity pay_data = data.getPay_data(); boolean success = data.isSuccess(); if (success) { String appid = pay_data.getAppid(); String partnerid = pay_data.getPartnerid(); String prepayid = pay_data.getPrepayid(); String noncestr = pay_data.getNoncestr(); String timestamp = pay_data.getTimestamp(); String packageX = pay_data.getPackageX(); String sign = pay_data.getSign(); String extData = "app data"; wechatPay(appid, partnerid, prepayid, noncestr, timestamp, packageX, sign, extData); }
微信支付存在一个回调类WXPayEntryActivity.java,这个文件位置为(你的应用包名称+.wxapi)详情可以参考官方demo,也可以直接拿过来自己用,但是要修改为你的appid:
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler { private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity"; private IWXAPI api; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.pay_result); api = WXAPIFactory.createWXAPI(this, "你的appid"); 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) { int errCode = resp.errCode; Logger.i("onPayFinish, errCode = " + errCode); if (errCode == 0) { //0 成功 展示成功页面 ToastUtil.toasts(getApplicationContext(), "支付成功"); Intent intent = new Intent(Constant.ACTION_NAME); sendBroadcast(intent); finish(); } else if (errCode == -1) { //-1 错误 可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。 ToastUtil.toasts(getApplicationContext(), "支付失败"); finish(); } else if (errCode == -2) { //-2 用户取消 无需处理。发生场景:用户不支付了,点击取消,返回APP。 ToastUtil.toasts(getApplicationContext(), "取消支付"); finish(); } } }
注意到上面的广播,是为了传给你支付的页面去进行下一步操作,记得注册和解除广播,然后在广播接受者里面进行微信支付成功下一步操作:
private BroadcastReceiver mBroadcastReceiver = new BaseBroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Logger.i("action", action); if (action.equals(Constant.ACTION_NAME)) { if (WECHATPAY.equals(payMethod)) { wechatPaySuccess(); } } } };
还有就是为了你的微信支付不至于跳转到回调的页面而进入成功后的下一个页面,可以将回调页面设置为透明的,如下是AndroidManifest.xml中的配置:
<!--微信支付回调界面--> <activity android:name=".wxapi.WXPayEntryActivity" android:theme="@android:style/Theme.Translucent" android:exported="true" android:launchMode="singleTop"/>