博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ReactNative接入微信API
阅读量:4086 次
发布时间:2019-05-25

本文共 20275 字,大约阅读时间需要 67 分钟。

写在前面

上一篇简单地讲了 ReactNative 如何接入支付宝支付,那么这一篇就介绍如何接入微信API吧。我们实际用到的一般有微信登录微信分享微信支付这三个功能。http://jafeney.com/2016/11/18/2016-11-17-wechat/

准备工作

微信的东西比较支付宝申请起来要略微麻烦点,步骤多,而且有些资质认证要给微信钱,心太黑。废话不多说,登录微信开放平台,创建你的App应用,改填的都填了,提交 —— 审核1~2天 —— 通过 —— 申请微信支付 —— 继续审核 … MD这步一次性通过是有多难 !

商户平台

微信支付申请通过了会收到一份邮件,里面有你的微信支付商户账号的信息(记得保存),然后用这个账号和密码登录微信商户平台。这里关键的一步是:

进入 账户中心 —> API安全 —> 设置一个32位的密钥

具体实现

准备工作都做好了,我们就可以开始开发了。

安装模块

感谢大react-native社区,为我们这种菜鸟提供了如此全面的微信三方模块react-native-wechat,完全能满足现阶段的所有微信API需求啊!

  • react-native-wechat交流群 336021910

支持npm安装:

1
npm install react-native-wechat --save

让 ReactNative完全支持ES7

asyncawaitES7比较新的提案,让ReactNative完全支持stage-0,首先我们需要安装 babel-preset-react-native-stage-0 模块:

1
npm install babel-preset-react-native-stage-0 --save-dev

并设置 .babelrc

1     
2
3
{     
"presets": [
"react-native-stage-0" ],
}

link和配置

上一篇已经介绍了 react-native link 命令,可以把客户端所需的模块链接到IOSAndroid目录里。

1
react-native link react-native-wechat

当然,只执行上面的命令还不够。我们还需要手动添加一些配置

IOS

微信的配置和支付宝差别不大。

(1)添加下面几个frameworklibrary

1     
2
3
4
5
SystemConfiguration.framework     
CoreTelephony.framework
libsqlite3.0
libc++
libz

xcode截图

注意:CoreTelephony.frameworklibc++zlibz,这三项和支付宝模块的重复,引一次就够了。

(2)添加 URL Schema ,值是你应用的微信appid

xcode截图

(3)给 LSApplicationQueriesSchemes 添加三个值 alipayweixinwechat

Xcode截图

或者直接编辑 Info.plist

1     
2
3
4
5
6
LSApplicationQueriesSchemes
alipay
weixin
wechat

注意:如果你不需要支付宝支付, alipay 可以不加

(4)修改 AppDelegate.m

如果你不需要支付宝支付,这个函数可以这么写:

1     
2
3
4
5
6
7
8
#import "../Libraries/LinkingIOS/RCTLinkingManager.h"     
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}

如果你既要支付宝支付,也需要微信支付。那么应该这么写:

1     
2
3
4
5
6
7
8
9
10
#import "../Libraries/LinkingIOS/RCTLinkingManager.h"     
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
if([[sourceApplication substringToIndex:10] isEqualToString:@"com.alipay"]){
[AlipayModule handleCallback:url];
}
return [RCTLinkingManager application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
}

Android

(1) 修改android/settings.gradle

1     
2
include       
':RCTWeChat'
project(
':RCTWeChat').projectDir =
new File(rootProject.projectDir,
'../node_modules/react-native-wechat/android')

(2)修改android/app/build.gradle

1     
2
3
dependencies {     
compile project(':RCTWeChat') // Add this line only.
}

(3)修改MainActivity.java or MainApplication.java

1     
2
3
4
5
6
7
8
9
10
11
12
13
14
import com.theweflex.react.WeChatPackage;             
// Add this line before public class MainActivity
...
/**
* A list of packages used by the app. If the app uses additional views
* or modules besides the default ones, add more packages here.
*/
@Override
protected List
getPackages() {
return Arrays.
asList(
new MainReactPackage(),
new WeChatPackage()
// Add this line
);
}

(4)创建一个新的package 取名wxapi ,在里面创建class 取名WXEntryActivity

1     
2
3
4
5
6
7
8
9
10
11
12
13
14
package your.      
package.wxapi;
import android.app.Activity;
import android.os.Bundle;
import com.theweflex.react.WeChatModule;
public
class WXEntryActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WeChatModule.handleIntent(getIntent());
finish();
}
}

(5)修改AndroidManifest.xml

1     
2
3
4
5
6
7
8
9
10

(6)修改 proguard-rules.pro

1     
2
3
-keep       
class com.tencent.mm.sdk.** {
*;
}

初始化模块

react-native-wechat 使用前必须初始化一次(有且仅一次)。建议放在项目的入口文件里:

1     
2
3
4
// ...省略     
componentDidMount() {
WeChat.registerApp(
'你的appid')
}

微信登录

微信登录需要用到的是 WeChat.sendAuthRequest 这个方法。

获取微信CODE

首先介绍一下它参数:

  • scope (必需) 应用授权作用域,如获取用户个人信息则填写 snsapi_userinfo
  • state (非必需) 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验

执行 WeChat.sendAuthRequest获取CODE:

1
let code =       
await WeChat.sendAuthRequest(
"snsapi_userinfo",
"123");

微信授权

该方法会返回一个字符串,类似 0114sg4t1F1Rc90jSw6t1Cf44t14sg4- 一串CODE。

获取微信access_token

包装一个 GET类型的fetch请求,URL如下:

1
https:      
//api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

这个接口会返回 access_token 和 用户的 openid。示例如下:

1     
2
3
4
5
6
7
8
{     
"access_token":
"JWk5IxV5bFGOdTm2A4zhuGuIB_xGRM5cPbU5nYbkuEihHu6FClMn5zjVZ6QCTYrMv_oCMxW8szuNAOadYIYo6wiOObeesEeNgHeWNvkJolQ",
"expires_in":
7200,
"refresh_token":
"WPhskoRBAmDyM1EbrPRvWSCU8LL3Ndn0Brong9ZG434L1Imkxugu2JKOghfIuP1P3JqcCyB2anxAwXRuFr7EMxP_rygeWy1Noi0zPJue_YU",
"openid":
"oDwRbw9zFEO36l3Vcq6bHXFWB13k",
"scope":
"snsapi_userinfo",
"unionid":
"o3KCIw-vFiuq0SBHe-3bhjbCQY3o"
}

获取微信授权后的用户信息

包装一个 GET类型的fetch请求,URL如下:

1
https:      
//api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

这个接口会返回 授权用户的微信基本信息,示例如下:

1     
2
3
4
5
6
7
8
9
10
11
12
{     
"openid":
"oDwRbw9zFEO36l3Vcq6bHXFWB13k",
"nickname":
"思^_^诚",
"sex":
1,
"language":
"zh_CN",
"city":
"Hangzhou",
"province":
"Zhejiang",
"country":
"CN",
"headimgurl":
"http://wx.qlogo.cn/mmopen/PiajxSqBRaEKujUoq5z4PScxKqQESxMxj6VDYnIHT4ZibVDMmSb69dq6EbLPAUJ15mMH9pIxFNu9JZszyx1F6ibcw/0",
"privilege": [],
"unionid":
"o3KCIw-vFiuq0SBHe-3bhjbCQY3o"
}

微信分享

微信分享用到的是 WeChat.shareToTimeline(opt)(分享到朋友圈) 和 WeChat.shareToSession(opt)(分享给微信好友或微信群),这两个方法的入参是一样的。

为了方便,微信分享我做成了一个react-native组件, 感兴趣的可以点击看看 

入参列表

  • thumbImage 分享出去的预览图
  • title 分享标题
  • webpageUrl 分享出去的网页地址

核心代码

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
/**     
* [分享到朋友圈]
* @param {[Object]} opt 入参对象
* @example { thumbImage:'', title: '', webpageUrl: '' }
*/
async handleShareWeixinCircle(opt) {
this.lock =
true
/* 异步操作锁 */
try {
let result =
await WeChat.shareToTimeline({
type:
"news",
...opt,
});
}
catch (e) {
console.error(e)
}
finally {
this.lock =
false
this.close()
}
}
/**
* [分享给微信好友或微信群]
* @param {[Object]} opt 入参对象
* @example { thumbImage:'', title: '', webpageUrl: '' }
*/
async handleShareWeixinFriend(opt) {
this.lock =
true
/* 异步操作锁 */
try {
let result =
await WeChat.shareToSession({
type:
"news",
...opt,
});
}
catch (e) {
console.error(e)
}
finally {
this.lock =
false
this.close()
}
}

我这里用到的是分享网页,更多分享功能参见 

微信支付

微信支付用到的是 WeChat.pay(opt) 方法

后端的工作

后端需要为我们提供一个支付接口 去调取微信支付的 “统一下单” 接口,然后返回下面这些东西: 

1     
2
3
4
5
6
7
8
9
{     
appid:
'',
//应用id
partnerid:
'',
// 商家向财付通申请的商家id
prepayid:
'',
// 预支付订单
noncestr:
'',
// 随机串,防重发
timestamp:
'',
// 时间戳,防重发
package:
'',
// 商家根据财付通文档填写的数据和签名
sign:
''
// 商家根据微信开放平台文档对数据做的签名
}

注意:后端要严格区分大小写,这几个变量必须都小写。否则会报 “支付签名验证失败” 这类的错误

前端的工作

有了react-native-wechat,微信支付其实也就调用一个方法的事情。类似支付宝支付的action,下面是最原始的实现代码(建议把fetch封装一下)。

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
export       
function weixinPay(opt) {
return
(dispatch) => {
const uri =
`http://${CONFIG.API_URI}/wx/pay`;
/*支付接口*/
const headers = {
...CONFIG.HEADERS,
'Authorization': opt.token,
};
/*发起支付请求*/
fetch(uri, {
method:
'POST',
headers: headers,
body:
JSON.stringify(opt.body)})
.then(
(response) => {
if (response.status ===
200) {
return response.json()
}
else {
return {
code: response.status}
}
})
.then(
(data) => {
if (
String(data.code) ==
'0') {
/*打开微信进行支付*/
pay(data.result, opt.success, opt.fail)
}
else {
/*预支付失败的后续操作*/
opt.error && opt.error(data.error.message)
}
})
}
}
async
function pay(res, success, fail) {
try {
let result =
await WeChat.pay({
partnerId: res.partnerid,
/*商家向财付通申请的商家id*/
prepayId: res.prepayid,
/*预支付订单*/
nonceStr: res.noncestr,
/*随机串,防重发*/
timeStamp: res.timestamp,
/*时间戳,防重发*/
package: res.package,
/*商家根据财付通文档填写的数据和签名*/
sign: res.sign,
/*商家根据微信开放平台文档对数据做的签名*/
});
/*支付成功的后续操作*/
success && success()
}
catch (error) {
/*支付失败的后续操作*/
fail && fail( error ===
-2 ?
"用户取消" :
"订单支付失败")
}
}

@欢迎关注我的  和 

你可能感兴趣的文章
从超链接调用ActionScript
查看>>
谈谈加密和混淆吧[转]
查看>>
TCP的几个状态对于我们分析所起的作用SYN, FIN, ACK, PSH,
查看>>
网络游戏客户端的日志输出
查看>>
关于按钮的mouseOver和rollOver
查看>>
《多线程服务器的适用场合》例释与答疑
查看>>
Netty框架
查看>>
Socket经验记录
查看>>
对RTMP视频流进行BitmapData.draw()出错的解决办法
查看>>
FMS 客户端带宽计算、带宽限制
查看>>
在线视频聊天(客服)系统开发那点事儿
查看>>
SecurityError Error 2148 SWF 不能访问本地资源
查看>>
Flex4的可视化显示对象
查看>>
Flex:自定义滚动条样式/隐藏上下箭头
查看>>
烈焰SWF解密
查看>>
Qt 静态编译后的exe太大, 可以这样压缩.
查看>>
3D游戏常用技巧Normal Mapping (法线贴图)原理解析——基础篇
查看>>
乘法逆元
查看>>
STL源码分析----神奇的 list 的 sort 算法实现
查看>>
Linux下用math.h头文件
查看>>