为了账号安全,请及时绑定邮箱和手机立即绑定

android 微信、支付宝支付踩坑之旅

标签:
Android

这两天为项目集成微信、支付宝支付功能写demo。多多少少遇到些坑,把这些记录一下,防止再掉进去。

自动代扣

又称“委托代扣”,“委托扣费”。使用不当会造成很严重的结果。也是比较流氓的功能。功能例子嘛:参考微博会员,爱奇艺会员,滴滴打车,Uber。基本就是在一次购买之后,每月会自动扣费,一旦中招很难察觉。但是无论微信还是支付宝,会员自动扣费的功能都是没有对普通开发者开放的,需要深度合作,查了半天资料,才确定金坷垃是不要想了。
不过意外的发现了两个开发文档,就当参考吧

微信委托代扣开发步骤指引 
支付宝代扣服务协议

下面是正篇

微信

微信的各种平台很多,支付开发,首先要来这里微信开放平台 
1.创建一个应用,
2.审核通过后,再申请开放微信支付的权限。
3.审核的过程中会发给你一个微信商户平台 的账号
做完了这些就可以开始正式开发了(总共大概需要几天时间,企业的话需要银行对公账户)
微信支付的demo比较坑,文档上说了好多资源,实际下载下来只有一个SDK的jar包和html的Javadoc,其他的基本靠猜,好在之前做过微信登录,基本逻辑差不多。(而且微信登录和微信支付其实SDK都是同一个)

微信SDKAndroid资源下载

微信支付开发文档

腾讯的产品,参数中代签名,签名逻辑从来都是很麻烦的,不过还好,这部分内容扔给服务端了,客户端这边就是掉个接口,所有参数就都有了
写个解析类大概这样

public class WxOrdersBean {     public String appid;     public String noncestr;     public String partnerid;     public String prepayid;     public String sign;     public String timestamp;     public WxOrdersBean() {     }     @Override     public String toString() {         return "WxOrdersBean{" +                 "appid='" + appid + '\'' +                 ", noncestr='" + noncestr + '\'' +                 ", partnerid='" + partnerid + '\'' +                 ", prepayid='" + prepayid + '\'' +                 ", sign='" + sign + '\'' +                 ", timestamp='" + timestamp + '\'' +                 '}';     } }

这时,在Activity中可以对微信发起支付请求了

public void payByWeChat(WxOrdersBean wxOrdersBean) {         //这些参数全部来自服务端         IWXAPI api = WXAPIFactory.createWXAPI(getApplicationContext(), null);         api.registerApp(AppID);         PayReq request = new PayReq();         request.appId = wxOrdersBean.appid;//微信开放平台审核通过的应用APPID         request.partnerId = wxOrdersBean.partnerid;//微信支付分配的商户号         request.prepayId = wxOrdersBean.prepayid;//微信返回的支付交易会话ID         request.packageValue = "Sign=WXPay";//暂填写固定值Sign=WXPay         request.nonceStr = wxOrdersBean.noncestr;//随机字符串,不长于32位。推荐随机数生成算法         request.timeStamp = wxOrdersBean.timestamp;//时间戳,请见接口规则-参数规定         request.sign = wxOrdersBean.sign;//签名,详见签名生成算法         api.sendReq(request);     }

这中间会遇到一些问题:
1.服务端签名错误,比如签名时没有区分大小写,拼写错误,再有就是可能没加入Sign=WXPay这类的
2.客户端APP签名错误,微信客户端在被调起时会检查发起者的签名,一般需要正式keystore签名过的才可以调起,建议先做微信分享或者微信登录,如果成功完成,那么微信支付基本不会是客户端的错误。这样有利于错误定位,排除客户端的原因。
3.关于微信的回调,按照微信一贯的蛋疼作风自然回调要在指定名字的 包名.wxapi.WXPayEntryActivity里

<activity        android:name=".wxapi.WXPayEntryActivity"        android:exported="true"        android:launchMode="singleTop" />

WXPayEntryActivity. java

public static final int CODE_SUCCESS = 0; public static final int CODE_ERROR = -1; public static final int CODE_CANCLE = -2; IWXAPI api; @Override public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);     api = WXAPIFactory.createWXAPI(getApplicationContext(), AppID);     api.handleIntent(getIntent(), this); }      @Override protected void onNewIntent(Intent intent) {     super.onNewIntent(intent);     api.handleIntent(intent, this); } @Override public void onReq(BaseReq baseReq) { } @Override public void onResp(BaseResp baseResp) {      if (baseResp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {         if (baseResp.errCode == CODE_SUCCESS) {             //在这里需要向自己的服务器发送请求查询是否真正成功          } else if (baseResp.errCode == CODE_ERROR) {          } else if (baseResp.errCode == CODE_CANCLE) {                     }                }  }

支付宝

其实支付宝要和微信做的也差不多,都是向自己服务端发起请求,获取参数和签名,通知支付宝客户端进行支付,返回结果后去自己服务器查询实际结果。
这里也会有几个问题
1.还是两个认证,一个蚂蚁金服商家账号,一个开发账号,这次可以是同一个用户名,不过都要填写认真资料。
2.还是签名,服务端的签名这次是需要自己生成RSA的公钥和私钥,并且把公约上传,用私钥签名。
3.注意沙箱环境!!!
沙箱环境用它生成的沙箱应用,新的APPID,公钥也需要重新上传,客户端需要在调起支付宝前加入代码

EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);

同时对应的要在文档下载指定的沙箱支付宝客户端,支付宝登录使用沙箱用户登录

 <activity       android:name="com.alipay.sdk.app.H5PayActivity"       android:configChanges="orientation|keyboardHidden|navigation|screenSize"       android:exported="false"       android:screenOrientation="behind"       android:windowSoftInputMode="adjustResize|stateHidden"></activity> <activity       android:name="com.alipay.sdk.app.H5AuthActivity"       android:configChanges="orientation|keyboardHidden|navigation"       android:exported="false"       android:screenOrientation="behind"       android:windowSoftInputMode="adjustResize|stateHidden"></activity>

另外不得不说。RxJava简直不要太爽,上述逻辑完全可以封装成一个方法

MyClient.orderApi().aliOrderRx(...)//这部分是retrofit 返回一个Observable 参数略                 .subscribeOn(Schedulers.io())                 .map(new Func1<AliOrderBean, String>() {                     @Override                     public String call(AliOrderBean aliOrderBean) {                         //这里将返回参数拼接成一段字符串,签名已经在参数中,不要在这里签名                         Map<String, String> params=OrderInfoUtil2_0.buildOrderParamMap(aliOrderBean);                         return OrderInfoUtil2_0.buildOrderParam(params);                     }                 })                 .map(new Func1<String, AliPayResult>() {                     @Override                     public AliPayResult call(String orderInfo) {                         //这里调用支付宝的支付SDK 是按照文档需要在非主线程                         EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);                         PayTask alipay = new PayTask(activity);                         Map<String, String> result = alipay.payV2(orderInfo, true);                         return new AliPayResult(result);                     }                 })                 .flatMap(new Func1<AliPayResult, Observable<String>>() {                     @Override                     public Observable<String> call(AliPayResult aliPayResult) {                         /**                          对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。                          */                         String resultStatus = aliPayResult.getResultStatus();                         // 判断resultStatus 为9000则代表支付成功                         if (TextUtils.equals(resultStatus, "9000")) {                                 //这里发起网络请求查询支付结果                                 return MyClient.getAliOrderRx(...);                           }                         //TODO 这里可能需要更合理的返回错误方式                         throw new Error(aliPayResult.toString());                     }                 })                 .observeOn(AndroidSchedulers.mainThread())                 //这里交个外部传入的observer来处理对应的结果                 .subscribe(observer);

阿里还是很良心的,demo写的相当全,上面的代码很大一部分都来自官方的demo中,包括AliPayResult,OrderInfoUtil2_0这两个类。

原文链接:http://www.apkbus.com/blog-822415-77933.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消