在开始之前,我想先对各位没做过微信支付的人吐槽一下,
——————–微信支付是我这辈子用过最难用,文档最烂,技术支持最恶心的第三方支付,没有第二。———–
希望没有吓到各位,但它真的是太烂了,每年还收300的服务费,真是太差劲了,Demo和文档都是三四年前的,真的是店大欺客。
废话不多讲,首先放一波官方的支付流程图,还是那句话,一定要认真看流程图,这样对你业务逻辑的处理有很大的提升。
知道了支付的大致流程,接下来就要分析如何支付了。在我的项目里,支付的流程是这样的:
首先,选择商品和数量等,点击下单,此时会在后台生成一张下单表,此表中的任何一条数据,有效期都在半小时内。半小时后该条下单数据就失效了。因此应该在半小时内完成支付。
下单后支付时,后台返回手机端预付单,此时调起微信完成支付。支付后的结果和支付宝一样,依然需要调用后台的数据以确保交易的正确性。虽然很繁琐,但是涉及到金钱的业务,一定要谨慎,作为程序员,我们也要对自己写的代码负责。
微信还有一点比较恶心的就是,所有数据的交换都是通过xml格式来进行的,疯狂吐槽半小时。
下面进入正题:首先,需要公司提供一个专用的账户,来申请商户平台。这里有一点很坑,就是在登录商户平台的时候,会让下载财付通的控件,我们最好使用IE浏览器,或者QQ浏览器,这个坑爹的控件对其他浏览器支持不是很好,总会发生错误。
商户在微信开放平台申请开发应用后,微信开放平台会生成APP的唯一标识APPID,我将它保存在全局常量。
public static final String WX_APP_ID = “wxxxxxxxxxxxxx”;
然后在项目的gradle文件中加入
compile ‘com.tencent.mm .opensdk:wechat-sdk-android-with-mta:1.4.0’
或者去官方下载jar包:点我下载
sync一下gradle编译完成。
在此之前,还有一些必要的事情要做:
将下面的代码粘贴至AndroidManifest文件下
<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="这里填写你的AppId"/>
</intent-filter>
</activity>
此外,还需要将Demo中wxapi包和包下的Activity拷贝至你项目的根目录,如图:
不出意外的话就可以调起支付了。
发起付款
这里假设我们已经拿到了预付单,在付款的Activity加入以下申明:
private IWXAPI msgApi;
在oncreate中初始化:
msgApi = WXAPIFactory.createWXAPI(this, Constant.WX_APP_ID);
msgApi.registerApp(Constant.WX_APP_ID);
假设现在已经获取到了预付单,那么此时就可以调起支付了
if (msg.what == ORDER_WX_PAY)
{
WXOrder wxOrder = JSONObject.parseObject(orders.getWxPayOrderString(), WXOrder.class);
showToast("获取订单中...");
// 将该app注册到微信
PayReq request = new PayReq();
request.appId = Constant.WX_APP_ID;
request.partnerId = Constant.WX_APP_BUSINESS; //微信支付分配的商户号
request.prepayId = wxOrder.getPrepayid(); //微信返回的支付交易会话ID
request.nonceStr = wxOrder.getNoncestr(); // 随机字符串
request.timeStamp = wxOrder.getTimestamp(); // 北京时间时间戳
request.packageValue = "Sign=WXPay";
request.sign = wxOrder.getSign(); //服务端生成的签名
App app = (App) this.getApplicationContext(); // 将ordersId保存到全局变量中,因为在微信回调页面无法获取它
app.setWxpayStatus(orders.getId());
if (wxOrder.getPrepayid() != null || "".equals(wxOrder.getPrepayid()))
{
msgApi.sendReq(request);
} else
{
showToast("订单号重复,请联系客服!");
}
}
此时,正常情况下,就会跳转到微信客户端支付界面,如果没有跳转,请确认AppId、app的签名是否正确,然后在商户平台修改正确。
–付款失败的原因有很多,但官网很负责的只给了一个错误码,所以,我们一般拿到-1的话,只能一步步排查错误了。
支付完成
在支付完成后,跳转到微信包的WXPayEntryActivity,