android接入,参考文献
- 流程:
- 客户端向自己的服务端申请订单,服务端同步到微信服务端
- 客户端收到订单后,调起微信进行支付
- 等微信返回后,会通知客户端,然后根据结果向自己的服务端请求相关信息
- 同时服务端会接受微信服务端的支付成功失败通知,也可以向微信服务端查询支付情况
- android的sdk已经升级过,从sdk变成了opensdk,下载wechat-sdk-android-without-mta-x.x.xjar或者wechat-sdk-android-with-mta-x.x.xjar
引入微信支付依赖,android studio的build.gradle文件中,添加如下依赖即可:
1
2
3dependencies {
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
}配置WXPayEntryActivity,从官网demo中copy一个来即可,必须放到app包下新建一个wxapi包里面
AndroidManifest.xml中注册
1
2
3
4
5
6
7
8
9
10
11<!--wx pay所需权限-->
<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"/>
<!--wx pay-->
<activity
android:name=".wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop">
<activity/>发送支付信息给服务端,自定义处理
跳转微信进行支付,java代码大致如下,需要注意的是需要运行到UI主线程,不然Toast.makeText等操作会崩溃
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29public static void wxPay(final String orderJson)
{
mAppActivity.runOnUiThread(new Runnable(){
public void run() {
try{
JSONObject json = new JSONObject(orderJson);
if(null != json){
PayReq req = new PayReq();
req.appId = APP_ID; //json.getString("appid");
req.partnerId = json.optString("partnerid");
req.prepayId = json.optString("prepayid");
req.nonceStr = json.optString("noncestr");
req.timeStamp = json.optString("timestamp");
req.packageValue = json.optString("package");
req.sign = json.optString("sign");
//req.extData = json.optString("extdata"); // optional
Toast.makeText(mAppActivity, "正在打开微信", Toast.LENGTH_SHORT).show();
mWXAPI.sendReq(req);
}else{
Toast.makeText(mAppActivity, "生成订单失败", Toast.LENGTH_SHORT).show();
}
}catch(Exception e){
Toast.makeText(mAppActivity, "支付失败"+e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}微信客户端回调支付结果处理,微信会自动回调到继续IWXAPIEventHandler的WXPayEntryActivity::public void onResp(BaseResp resp),如果在cocos上调用,同样要注意让回调运行在GLThread中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34public static void onWXResp(BaseResp resp) {
if (resp instanceof SendAuth.Resp) {
//
}
else if (resp instanceof SendMessageToWX.Resp) {
//
}
// com.tencent.mm.opensdk.constants.ConstantsAPI;
// resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX
else if (resp instanceof PayResp) {
final PayResp payResp = (PayResp)resp;
if (payResp.errCode == 0) {
mAppActivity.runOnGLThread(new Runnable(){
public void run() {
onWXpaySuccess("支付成功");
}
});
} else {
final String resultStatus;
if (payResp.errCode == -2) {
resultStatus = "您取消了支付";
} else {
resultStatus = "支付失败";
}
mAppActivity.runOnGLThread(new Runnable(){
public void run() {
onWXpayFail(resultStatus);
}
});
}
}
}
ios接入,参考文献
- 接入流程跟android是一样的,区别的是,一般ios游戏为了上AppStore,一般不接带支付功能的sdk,所以用微信去除支付功能的sdk
将解压的微信OpenSDK文件夹拷贝到项目文件夹下,并导入开发环境中。
1
2
3
4libWeChatSDK.a
WechatAuthSDK.h
WXApi.h
WXApiObject.h并根据官方文档导入依赖库
- 添加URL Schemes, 点击项目名称,点击“Info”选项卡,在“URL Types”选项中,点击“+”, 在“URL Schemes”中输入微信的注册码
使用URLScheme调起weixin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82void wxPay(const std::string& orderJson, const std::function<void(bool, const std::string&)>& callback)
{
std::string output = "";
// 隐藏微信地址
Base64Decode("d2VpeGluOi8vYXBwL3d4NWI5YmZkZGFiNGZiZjQyNi9wYXkvPw==", &output);
rapidjson::Document document;
document.Parse(orderJson.c_str());
std::string partnerid, prepayid, noncestr, timestamp, package, sign, extdata;
bool bfirst = true;
if ( document.HasMember("extdata") ) {
rapidjson::Value& v = document["extdata"];
if (v.IsString()) {
extdata = v.GetString();
if (!extdata.empty()) {
output += "extData=" + extdata;
bfirst = false;
}
}
}
if ( document.HasMember("noncestr") ) {
rapidjson::Value& v = document["noncestr"];
if (v.IsString()) {
noncestr = v.GetString();
if (noncestr.empty()) { callback(false, "支付失败"); return;}
if ( bfirst ) {
bfirst = false;
output += "nonceStr=" + noncestr;
} else {
output += "&nonceStr=" + noncestr;
}
}
}
if ( document.HasMember("package") ) {
rapidjson::Value& v = document["package"];
if (v.IsString()) {
package = v.GetString();
package = package.replace(package.find("="), 1, "\%\%3D");
if (package.empty()) { callback(false, "支付失败"); return;}
output += "&package=" + package;
}
}
if ( document.HasMember("partnerid") ) {
rapidjson::Value& v = document["partnerid"];
if (v.IsString()) {
partnerid = v.GetString();
if (partnerid.empty()) { callback(false, "支付失败"); return;}
output += "&partnerId=" + partnerid;
}
}
if ( document.HasMember("prepayid") ) {
rapidjson::Value& v = document["prepayid"];
if (v.IsString()) {
prepayid = v.GetString();
if (prepayid.empty()) { callback(false, "支付失败"); return;}
output += "&prepayId=" + prepayid;
}
}
if ( document.HasMember("timestamp") ) {
rapidjson::Value& v = document["timestamp"];
if (v.IsString()) {
timestamp = v.GetString();
if (timestamp.empty()) { callback(false, "支付失败"); return;}
output += "&timeStamp=" + timestamp;
}
}
if ( document.HasMember("sign") ) {
rapidjson::Value& v = document["sign"];
if (v.IsString()) {
sign = v.GetString();
if (sign.empty()) { callback(false, "支付失败"); return;}
output += "&sign=" + sign;
}
}
output += "&signType=SHA1";
setWXpayCallback(callback);
NSString * pUrl = [NSString stringWithUTF8String:output.c_str()];
NSURL* url = [NSURL URLWithString:pUrl];
[[UIApplication sharedApplication] openURL:url];
}等待微信回调,头文件中App继承WXApiDelegate,sdk会回调到openURL,但并不会回调到onResp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
return [WXApi handleOpenURL:url delegate:self];
}
// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
if ([url.absoluteString rangeOfString:APP_ID].length) {
auto callback = getWXpayCallback();
if ( callback ) {
// 微信支付,微信回调的时候回回传ret参数,这样来区分支付知否成功
NSArray *array = [url.absoluteString componentsSeparatedByString:@"ret="];
NSInteger ret = [array.lastObject integerValue];
// 调起微信结果返回
// ret: 0成功支付 -2取消支付 -1其他原因
if ( ret == 0 ) {
callback(true, "支付成功");
} else if ( ret==-2 ) {
callback(false, "您取消了支付");
} else {
callback(false, "支付失败");
}
setWXpayCallback(nullptr);
}
}
else {
return [WXApi handleOpenURL:url delegate:self];
}
return YES;
}