100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > ReactNative接入微信API 接入支付宝支付

ReactNative接入微信API 接入支付宝支付

时间:2022-12-11 00:04:04

相关推荐

ReactNative接入微信API 接入支付宝支付

写在前面

上一篇简单地讲了ReactNative如何接入支付宝支付,那么这一篇就介绍如何接入微信API吧。我们实际用到的一般有微信登录、微信分享、微信支付这三个功能。

准备工作

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

商户平台

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

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

具体实现

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

安装模块

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

github地址react-native-wechat交流群 336021910

支持npm安装:

npm install react-native-wechat --save1

ReactNative完全支持ES7

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

npm install babel-preset-react-native-stage-0 --save-dev1

并设置.babelrc

{"presets": [ "react-native-stage-0" ],}123

link和配置

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

react-native link react-native-wechat1

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

IOS

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

(1)添加下面几个frameworklibrary

SystemConfiguration.frameworkCoreTelephony.frameworklibsqlite3.0libc++libz12345

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

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

(3)给LSApplicationQueriesSchemes添加三个值alipayweixinwechat

或者直接编辑Info.plist

<key>LSApplicationQueriesSchemes</key><array><string>alipay</string><string>weixin</string><string>wechat</string></array>123456

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

(4)修改AppDelegate.m

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

#import "../Libraries/LinkingIOS/RCTLinkingManager.h"- (BOOL)application:(UIApplication *)application openURL:(NSURL *)urlsourceApplication:(NSString *)sourceApplication annotation:(id)annotation{return [RCTLinkingManager application:application openURL:urlsourceApplication:sourceApplication annotation:annotation];}12345678

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

#import "../Libraries/LinkingIOS/RCTLinkingManager.h"- (BOOL)application:(UIApplication *)application openURL:(NSURL *)urlsourceApplication:(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];}12345678910

Android

(1) 修改android/settings.gradle

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

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

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

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

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.*/@Overrideprotected List<ReactPackage> getPackages() {return Arrays.<ReactPackage>asList(new MainReactPackage(), new WeChatPackage() // Add this line);}1234567891011121314

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

package your.package.wxapi;import android.app.Activity;import android.os.Bundle;import com.theweflex.react.WeChatModule;public class WXEntryActivity extends Activity{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);WeChatModule.handleIntent(getIntent());finish();}}1234567891011121314

(5)修改AndroidManifest.xml

<manifest><application><!-- 微信Activity --><activityandroid:name=".wxapi.WXEntryActivity"android:label="@string/app_name"android:exported="true"/></application></manifest>12345678910

(6)修改proguard-rules.pro

-keep class com.tencent.mm.sdk.** {*;}123

初始化模块

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

// ...省略componentDidMount() {WeChat.registerApp('你的appid')}1234

微信登录

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

获取微信CODE

首先介绍一下它参数:

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

执行WeChat.sendAuthRequest获取CODE:

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

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

获取微信access_token

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

https://api./sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code1

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

{"access_token": "JWk5IxV5bFGOdTm2A4zhuGuIB_xGRM5cPbU5nYbkuEihHu6FClMn5zjVZ6QCTYrMv_oCMxW8szuNAOadYIYo6wiOObeesEeNgHeWNvkJolQ","expires_in": 7200,"refresh_token": "WPhskoRBAmDyM1EbrPRvWSCU8LL3Ndn0Brong9ZG434L1Imkxugu2JKOghfIuP1P3JqcCyB2anxAwXRuFr7EMxP_rygeWy1Noi0zPJue_YU","openid": "oDwRbw9zFEO36l3Vcq6bHXFWB13k","scope": "snsapi_userinfo","unionid": "o3KCIw-vFiuq0SBHe-3bhjbCQY3o"}12345678

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

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

https://api./sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID1

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

{"openid": "oDwRbw9zFEO36l3Vcq6bHXFWB13k","nickname": "思^_^诚","sex": 1,"language": "zh_CN","city": "Hangzhou","province": "Zhejiang","country": "CN","headimgurl": "/mmopen/PiajxSqBRaEKujUoq5z4PScxKqQESxMxj6VDYnIHT4ZibVDMmSb69dq6EbLPAUJ15mMH9pIxFNu9JZszyx1F6ibcw/0","privilege": [],"unionid": "o3KCIw-vFiuq0SBHe-3bhjbCQY3o"}123456789101112

微信分享

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

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

入参列表

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

核心代码

/*** [分享到朋友圈]* @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 = falsethis.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 = falsethis.close()}}12345678910111213141516171819222324252627282930313233343536373839

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

微信支付

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

后端的工作

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

{appid: '', //应用idpartnerid: '', // 商家向财付通申请的商家idprepayid: '', // 预支付订单noncestr: '', // 随机串,防重发timestamp: '', // 时间戳,防重发package: '', // 商家根据财付通文档填写的数据和签名sign: '' // 商家根据微信开放平台文档对数据做的签名}123456789

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

前端的工作

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

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 ? "用户取消" : "订单支付失败")}}12345678910111213141516171819222324252627282930313233343536373839404142434445

写在前面

重申一下,ReactNative开发的AppNativeApp,不是WebApp或者HybridApp,所以我们需要开通的是支付宝的App支付功能,别申请错了。申请完成之后就可以接下去开发了。

支付宝支付

接入支付宝支付前建议先查看支付宝官方文档,先按照要求创建应用并完成配置。不过要注意以下两点:

第一,App支付不能在沙箱做测试,所以我们需要先 “上线” 应用,这个过程会有1天的审核时间。

第二,调试时建议添加个一分钱的商品作为测试商品,开发免不了要支付几次。

安装模块

支付宝支付我们使用了ReactNative社区推荐的react-native-yunpeng-alipay模块,可以使用npm安装

npm install react-native-yunpeng-alipay --save1

link引用

最新版React Native(>=0.31) 已经支持link命令,不需要再使用三方的rnpmlink引用了。

react-native link react-native-yunpeng-alipay1

这个操作会把react-native-yunpeng-alipay模块下的客户端模块自动映射到 ReactNative工程的对应的 IOS和 Android目录里。 注意,自动link并不是万能的,有些模块我们需要再手动添加一些引用。

IOS端配置

对于IOS端,除了上面的link操作之外,我们还需要手动做下面的三件事:

添加Frameworks和Libraries

打开xcode,TARGET->General->Linked Frameworks and Libraries,添加

CoreMotion.frameworkCoreTelephony.frameworklibc++libz

添加URL Schema

打开Info.plist,添加一项URL types

触发回调

打开AppDelegate.m,添加一个函数来触发支付完成后的回调

#import "AlipayModule.h"- (BOOL)application:(UIApplication *)application openURL:(NSURL *)urlsourceApplication:(NSString *)sourceApplication annotation:(id)annotation{[AlipayModule handleCallback:url];return YES;}1234567

Android端配置

Android端配置比较简单,除了上面的link操作外,我们还需要修改Manifest文件

修改Manifest

在商户应用工程的AndroidManifest.xml文件里面添加声明:

<activity android:name="com.alipay.sdk.app.H5PayActivity"android:configChanges="orientation|keyboardHidden|navigation"android:exported="false"android:screenOrientation="behind" ></activity><activity android:name="com.alipay.sdk.auth.AuthActivity"android:configChanges="orientation|keyboardHidden|navigation"android:exported="false"android:screenOrientation="behind" ></activity>123456789101112

和权限声明:

<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />12345

添加混淆规则

在商户应用工程的proguard-project.txt里添加以下相关规则:

-libraryjars libs/alipaySDK-0602.jar-keep class com.alipay.android.app.IAlixPay{*;}-keep class com.alipay.android.app.IAlixPay$Stub{*;}-keep class com.alipay.android.app.IRemoteServiceCallback{*;}-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}-keep class com.alipay.sdk.app.PayTask{ public *;}-keep class com.alipay.sdk.app.AuthTask{ public *;}12345678

Action封装

我们的App开发采用的是redux框架,为了方便使用,我把支付宝支付封装成了Action,你可以参考一下。

/*** @desc 三方支付* @author Jafeney* @detetime -11-08**/import Alipay from 'react-native-yunpeng-alipay'import * as CONFIG from '../config'export function alipay(opt) {return (dispatch) => {const uri = `http://${ CONFIG.API_URI }/alipay/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') {/*打开支付宝进行支付*/Alipay.pay(data.result).then((data) => {if (data.length && data[0].resultStatus) {/*处理支付结果*/switch (data[0].resultStatus) {case "9000":opt.success && opt.success(data)break;case "8000":opt.fail && opt.fail('支付结果未知,请查询订单状态')break;case "4000":opt.fail && opt.fail('订单支付失败')break;case "5000":opt.fail && opt.fail('重复请求')break;case "6001":opt.fail && opt.fail('用户中途取消')break;case "6002":opt.fail && opt.fail('网络连接出错')break;case "6004":opt.fail && opt.fail('支付结果未知,请查询订单状态')break;default:opt.fail && opt.fail('其他失败原因')break;}} else {opt.fail && opt.fail('其他失败原因')}}, (err) => {opt.fail && opt.fail('支付失败,请重新支付')})} else {opt.error && opt.error('支付参数错误')}})}}123456789101112131415161718192223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071

@欢迎关注我的github和个人博客 -Jafeney

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。