微信SDK的支付功能接入简单梳理。
首先说一下,你需要的官网都有,但是官网提供的东西不管新旧与否先给你放上去,部分地方提供的链接点击时还提示404,不同的页面提示相同的下载内容(demo)还不一样,表示很无奈(lai)。
这里把几个主要点罗列出来,给大家节省点宝贵的时间,有什么错误希望大家指正(默认微信支付平台商户申请及应用创建略去,商务小伙伴已经把AppID和秘钥给到你了,这里只说一下客户端需要处理的相关事宜)。
开发者平台:主要是针对开发者,比如:创建应用,获取appid
商户平台:主要是商户上面的一些管理,比如:可以查看流水,订单呀
步骤一:下载官方示例,示例下载地址。
点击下载Android平台所需的APP支付文件。
点击“Android头文件和库下载”下载后会跳转到该页面:
接着点击Android开发工具包,下载对应的lib库。
解压以后的文件目录里有两个jar。
细节1:这两个jar不是都得用,不知道的把两个jar都考到项目工程下,肯定会给你个jar重复的错误提示。这里依据需求进行选择,这两个依赖包的区别是前者包含统计功能,后者没有。
自己这里选择的是第二个,没有统计功能且包体小一点的。
步骤二,新建公共lib库,将对应jar包放入项目工程中待用.(lib公共库的创建)
步骤三,从Demo示例的工程目录下拷入WXEntryActivity.java文件到你的项目目录下,一定要保证:
该文件存放的目录格式是这样的:com.package.name.wxapi,前面com.package.name是你真正的包名,wxapi是同级包。编辑修改对应文件,其他无用部分都不使用。以下是整个文件剩下内容。
public class WXEntryActivity extends Activity implements IWXAPIEventHandler{
// IWXAPI 是第三方app和微信通信的openapi接口
private IWXAPI api;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.entry);这一行不需要,直接注释。
// 通过WXAPIFactory工厂,获取IWXAPI的实例
api = WXAPIFactory.createWXAPI(this, Constants.APP_ID, false);
// 将该app注册到微信
api.registerApp(APP_ID);//你的AppID,最好写在Lua端或者服务端。
//注意:
//第三方开发者如果使用透明界面来实现WXEntryActivity,需要判断handleIntent的返回值,如果返回值为false,则说明入参不合法未被SDK处理,应finish当前透明界面,避免外部通过传递非法参数的Intent导致停留在透明界面,引起用户的疑惑
try {
api.handleIntent(getIntent(), this);
} catch (Exception e) {
e.printStackTrace();
}
}
@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){
if (resp.errCode == 0){
Toast.makeText(this, "支付成功!", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "支付失败!", Toast.LENGTH_SHORT).show();
}
}
finish();
}
}
步骤四,支付代码部分。
支付部分也是最主要的部分,基于cocos2d-lua的项目,这里涉及到Lua调用Java的需求,简单说一下:
1,你可以直接使用cocos封装好的
luaj.callStaticMethod(param1, param2, param3, param4)
param1:"com.game.mainactivity",回调到java的对应类的完整路径(字符串类型)
param2:"on_pay",回调到java的对应方法名称(字符串类型)
param3:{...},调用java方法时需要传入的参数信息(table类型)
param4:"(Ljava/lang/String;)V",方法的签名。具体可参考:JNI方法签名
2,直接在C++里写一个专门处理支付的方法,导出给lua使用,然后在C++里使用JNI回调到java。
2种方法本质基本一样,这样在java端对应的方法里解析传入的参数,取到对应所需的数值:商品ID,商品价格等等即可。
------------------------------重点线-------------------------------------------
官网文档说明位置:支付接口-服务器部分,支付接口所需参数-客户端部分
一,目前微信最新的支付接入,需要四个参数:
APP_ID:应用唯一标示
PARTNER_ID:应用商户ID号
PAY_KEY:应用私钥
PRE_PAY_ID:预支付交易订单号(商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再在APP里面调起支付,用于后续接口调用中使用,该值有效期为2小时)
上面四个变量的命名无特殊要求,自己清楚对应数值含义就好,个人建议这些东西最好放在服务端,由客户端请求后传入支付调用接口处,自己是写在lua层的,出包时对lua文件做了加密。这里的预支付订单是有服务器请求微信支付后台取到,发给客户端的,这个数值在后面的调用支付接口时会用到。
二,客户端调起支付接口时所需的参数(注意相应的字段类型)
从应用ID到预支付ID都是已有的,扩展字段填入给到的示例值即可。
随机字符串:一定要和服务器采用相同的算法生成,统一使用如下方法:
private static String genNonceStr() {
Random r = new Random(System.currentTimeMillis());
return MD5.getMessageDigest((WXPayConfig.APP_ID + r.nextInt(10000) + System.currentTimeMillis()).getBytes());
}
时间戳:
String timestamp = "" + System.currentTimeMillis();
签名:参考官网示例即可
这里直接给出方法逻辑
List<NameValuePair> signParams = new LinkedList<NameValuePair>();
signParams.add(new BasicNameValuePair("appid", payReq.appId));
signParams.add(new BasicNameValuePair("noncestr", payReq.nonceStr));
signParams.add(new BasicNameValuePair("package", payReq.packageValue));
signParams.add(new BasicNameValuePair("partnerid", payReq.partnerId));
signParams.add(new BasicNameValuePair("prepayid", payReq.prepayId));
signParams.add(new BasicNameValuePair("timestamp", payReq.timeStamp));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < signParams.size(); i++) {
sb.append(signParams.get(i).getName());
sb.append('=');
sb.append(signParams.get(i).getValue());
sb.append('&');
}
sb.append("key=");
sb.append(WXPayConfig.PAY_KEY);//该字段很重要
String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
return appSign;
整个支付方法的核心代码:
//支付方法,参数prePayId由客户端请求服务器获得的预支付ID通过JNI回传到客户端的数值
public static void wxPay(String prePayId) {
IWXAPI msgApi = WXAPIFactory.createWXAPI(mContext, WXPayConfig.APP_ID);
msgApi.registerApp(WXPayConfig.APP_ID);
if (!msgApi.isWXAppInstalled() || !msgApi.isWXAppSupportAPI()) {
Toast.makeText(mContext, "您没有安装微信,或者微信版本过低,请要先安装或者升级", Toast.LENGTH_SHORT).show();
return;
}
PayReq payRequest = new PayReq();
payRequest.appId = WXPayConfig.APP_ID;
payRequest.partnerId = WXPayConfig.PARTNER_ID;
payRequest.prepayId = prePayId;
payRequest.nonceStr = genNonceStr();
payRequest.timeStamp = "" + System.currentTimeMillis();
payRequest.packageValue = "Sign=WXPay";
payRequest.sign = genAppSign(payRequest);
msgApi.sendReq(payRequest);
}
这样微信支付的整个流程基本就走通了,支付以后会回调你在WXEntryActivity里的如下方法提示你支付结果
@Override
public void onResp(BaseResp resp) {
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
if (resp.errCode == 0) {
Toast.makeText(this, "支付成功 ", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "支付失败,请重试 ", Toast.LENGTH_SHORT).show();
}
}
}
细节:
1,AndroidManifest.xml里添加一下activity标签定义:
<activity android:name="项目包名.wxapi.WXEntryActivity" android:exported="true" />
2,接入微信SDK关于分享,登录,支付的等功能,为了确保能正常使用及安全支付,都需要在开放平台绑定商户应用包名和应用签名,设置好后才能正常发起支付。
应用签名的生成方式:
1,确保app使用包名和开放平台中填入的包名一直,然后下载对应的签名工具
即可生成对应的签名,填入应用开放平台即可。
这就是微信支付SDK接入的大概流程