expo-alipay-sdk 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +281 -0
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/build.gradle +22 -0
- package/android/src/main/AndroidManifest.xml +14 -0
- package/android/src/main/java/com/goldstar/alipay/AlipayModule.java +140 -0
- package/android/src/main/java/com/goldstar/alipay/AlipayPackage.java +26 -0
- package/android/src/main/java/com/goldstar/alipay/PayResult.java +46 -0
- package/app.plugin.js +53 -0
- package/expo-alipay.podspec +32 -0
- package/ios/Alipay.h +9 -0
- package/ios/Alipay.mm +143 -0
- package/ios/iOS_SDK/AlipaySDK.bundle/alipay_msp_back@2x.png +0 -0
- package/ios/iOS_SDK/AlipaySDK.bundle/alipay_msp_refresh@2x.png +0 -0
- package/ios/iOS_SDK/AlipaySDK.bundle/bar@2x.png +0 -0
- package/ios/iOS_SDK/AlipaySDK.bundle/bridge.js +1 -0
- package/ios/iOS_SDK/AlipaySDK.bundle/bridge_v2.js +79 -0
- package/ios/iOS_SDK/AlipaySDK.bundle/refresh@2x.png +0 -0
- package/ios/iOS_SDK/AlipaySDK.bundle/refresh_click@2x.png +0 -0
- package/ios/iOS_SDK/AlipaySDK.bundle/shutdown@2x.png +0 -0
- package/ios/iOS_SDK/AlipaySDK.bundle/shutdown_click@2x.png +0 -0
- package/ios/iOS_SDK/AlipaySDK.framework/AlipaySDK +0 -0
- package/ios/iOS_SDK/AlipaySDK.framework/AlipaySDK-inside-Info.plist +0 -0
- package/ios/iOS_SDK/AlipaySDK.framework/Headers/AFServiceCenter.h +68 -0
- package/ios/iOS_SDK/AlipaySDK.framework/Headers/AFServiceResponse.h +43 -0
- package/ios/iOS_SDK/AlipaySDK.framework/Headers/APCellularHTTPSClient.h +73 -0
- package/ios/iOS_SDK/AlipaySDK.framework/Headers/APDeductSDK.h +27 -0
- package/ios/iOS_SDK/AlipaySDK.framework/Headers/APayAuthInfo.h +33 -0
- package/ios/iOS_SDK/AlipaySDK.framework/Headers/AlipaySDK.h +253 -0
- package/ios/iOS_SDK/AlipaySDK.framework/Headers/AlipaySDKModule.h +18 -0
- package/ios/iOS_SDK/AlipaySDK.framework/Headers/MQPWebViewResourcesManager.h +37 -0
- package/ios/iOS_SDK/AlipaySDK.framework/Modules/module.modulemap +14 -0
- package/package.json +62 -0
- package/src/index.d.ts +69 -0
- package/src/index.js +164 -0
package/README.md
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# expo-alipay
|
|
2
|
+
|
|
3
|
+
专为 Expo 打造的支付宝支付集成解决方案。
|
|
4
|
+
更新于2025年12月。
|
|
5
|
+
基于最新支付宝官方 SDK 开发,支持 iOS 和 Android 双平台,为 Expo 项目提供稳定可靠的支付宝支付功能支持:
|
|
6
|
+
|
|
7
|
+
- ✅ **支付宝支付** - 完整的支付功能集成
|
|
8
|
+
|
|
9
|
+
## 前期准备
|
|
10
|
+
|
|
11
|
+
在开始使用本库之前,请确保你已经准备好以下内容:
|
|
12
|
+
|
|
13
|
+
### 必需配置
|
|
14
|
+
|
|
15
|
+
1. **支付宝 AppID**
|
|
16
|
+
- 在 [支付宝开放平台](https://open.alipay.com/) 注册并创建移动应用
|
|
17
|
+
- 获取应用的 **AppID**
|
|
18
|
+
- 完成应用的基本信息填写和审核
|
|
19
|
+
|
|
20
|
+
2. **iOS URL Scheme 配置**(仅 iOS 需要)
|
|
21
|
+
- 为什么需要:iOS 系统需要通过 URL Scheme 来实现应用间的跳转和回调。如果不配置,将导致:
|
|
22
|
+
- ❌ 无法接收支付回调
|
|
23
|
+
- 详细配置步骤请参考下方配置说明
|
|
24
|
+
|
|
25
|
+
### 支付功能额外配置
|
|
26
|
+
|
|
27
|
+
如果你需要使用支付宝支付功能,还需要额外准备:
|
|
28
|
+
|
|
29
|
+
- **商户私钥** - 用于签名验证(**必须在服务端完成,严禁放在客户端**)
|
|
30
|
+
- **支付宝公钥** - 用于验证支付结果
|
|
31
|
+
|
|
32
|
+
> 💡 **重要提示**:支付参数签名过程和私钥 **必须在 App 服务端** 完成,示例项目中的签名流程仅供开发时参考。严禁将私钥放在客户端,否则可能造成资金损失和安全风险。
|
|
33
|
+
|
|
34
|
+
## 快速开始(0 配置)
|
|
35
|
+
|
|
36
|
+
本包采用 0 配置设计,安装后只需配置 `app.json` 即可使用,所有 SDK 文件和原生配置都会自动处理。
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx expo install expo-alipay-sdk
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
或
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
yarn add expo-alipay-sdk
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 配置步骤
|
|
49
|
+
|
|
50
|
+
### 1. 安装插件
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npx expo install expo-alipay-sdk
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
或
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
yarn add expo-alipay-sdk
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 2. 配置 app.json
|
|
63
|
+
|
|
64
|
+
在项目根目录的 `app.json` 或 `app.config.js` 中添加插件配置:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"expo": {
|
|
69
|
+
"plugins": [
|
|
70
|
+
"expo-alipay-sdk"
|
|
71
|
+
],
|
|
72
|
+
"ios": {
|
|
73
|
+
"infoPlist": {
|
|
74
|
+
"LSApplicationQueriesSchemes": ["alipay", "alipays"],
|
|
75
|
+
"CFBundleURLTypes": [
|
|
76
|
+
{
|
|
77
|
+
"CFBundleTypeRole": "Editor",
|
|
78
|
+
"CFBundleURLName": "alipay",
|
|
79
|
+
"CFBundleURLSchemes": ["你的AppScheme"]
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"android": {
|
|
85
|
+
"package": "com.your.package.name"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**重要说明:**
|
|
92
|
+
- 将 `你的AppScheme` 替换为你在支付宝开放平台配置的实际 URL Scheme
|
|
93
|
+
- `android.package` 需要设置为你的应用包名
|
|
94
|
+
- iOS 的 `CFBundleURLSchemes` 必须与支付宝开放平台配置的 URL Scheme 一致
|
|
95
|
+
|
|
96
|
+
### 3. 执行预构建
|
|
97
|
+
|
|
98
|
+
运行以下命令生成原生项目:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npx expo prebuild
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**就这么简单!** 插件会自动完成所有配置:
|
|
105
|
+
|
|
106
|
+
#### 自动配置功能
|
|
107
|
+
- ✅ **iOS SDK 自动集成**:自动配置支付宝 iOS SDK Framework 和 Bundle
|
|
108
|
+
- ✅ **Android SDK 自动依赖**:自动添加支付宝 Android SDK Maven 依赖
|
|
109
|
+
- ✅ **ProGuard 混淆规则**:自动添加支付宝 SDK 的混淆规则,防止代码混淆导致的功能异常
|
|
110
|
+
- ✅ **Android 11+ 兼容**:自动添加 `<queries>` 标签,确保在 Android 11 及以上版本正常使用
|
|
111
|
+
- ✅ **iOS URL Scheme**:自动配置 URL Schemes 和查询方案
|
|
112
|
+
|
|
113
|
+
> ⚠️ **重要提示**:不建议手动修改原生项目配置文件(如 `Info.plist`、`AndroidManifest.xml` 等),因为这些文件在运行 `npx expo prebuild` 时会被重新生成,手动修改会被覆盖。如果遇到配置问题,欢迎提交 [Issue](https://github.com/your-username/expo-alipay/issues) 或 [Pull Request](https://github.com/your-username/expo-alipay/pulls)。
|
|
114
|
+
|
|
115
|
+
## 调用库
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
import * as Alipay from 'expo-alipay-sdk';
|
|
119
|
+
|
|
120
|
+
// 注册应用
|
|
121
|
+
Alipay.registerApp('你的AppID', '你的UniversalLink(可选)').then((result) => {
|
|
122
|
+
console.log("注册成功:", result);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// 发起支付
|
|
126
|
+
const orderInfo = "你的订单信息字符串(由服务端生成并签名)";
|
|
127
|
+
Alipay.pay(orderInfo).then((result) => {
|
|
128
|
+
console.log("支付成功:", result);
|
|
129
|
+
}).catch((error) => {
|
|
130
|
+
console.log("支付失败:", error);
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## 回调事件订阅
|
|
135
|
+
|
|
136
|
+
支付完成后会触发回调事件,请在调用支付方法前提前添加事件监听。
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
import { DeviceEventEmitter } from 'react-native';
|
|
140
|
+
import * as Alipay from 'expo-alipay-sdk';
|
|
141
|
+
|
|
142
|
+
// 注册应用
|
|
143
|
+
Alipay.registerApp('your_app_id', 'your_universal_link');
|
|
144
|
+
|
|
145
|
+
// 监听支付回调
|
|
146
|
+
DeviceEventEmitter.addListener('Alipay_Resp', resp => {
|
|
147
|
+
console.log('支付宝回调:', resp);
|
|
148
|
+
|
|
149
|
+
if (resp.type === 'PayResult.Resp') {
|
|
150
|
+
// 支付回调
|
|
151
|
+
if (resp.resultStatus === '9000') {
|
|
152
|
+
console.log('支付成功');
|
|
153
|
+
} else {
|
|
154
|
+
console.log('支付失败:', resp.memo);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## API 文档
|
|
161
|
+
|
|
162
|
+
本库支持 `TypeScript`,使用 `Promise` 或 `async/await` 来接收返回。
|
|
163
|
+
|
|
164
|
+
### registerApp(appId, universalLink?) 注册应用
|
|
165
|
+
|
|
166
|
+
- `appId` {String} 支付宝应用 ID
|
|
167
|
+
- `universalLink` {String} iOS Universal Link(可选,仅 iOS 需要)
|
|
168
|
+
- returns {Promise<Boolean>} 注册是否成功
|
|
169
|
+
|
|
170
|
+
此方法应该在应用启动时全局调用一次。
|
|
171
|
+
|
|
172
|
+
```js
|
|
173
|
+
import * as Alipay from 'expo-alipay-sdk';
|
|
174
|
+
|
|
175
|
+
Alipay.registerApp('your_app_id', 'your_universal_link');
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### pay(orderInfo) 发起支付
|
|
179
|
+
|
|
180
|
+
- `orderInfo` {String} 支付订单信息字符串(由服务端生成并签名)
|
|
181
|
+
- returns {Promise<PayResult>} 支付结果
|
|
182
|
+
|
|
183
|
+
**重要说明:**
|
|
184
|
+
- `orderInfo` 必须由服务端生成并签名,严禁在客户端进行签名操作
|
|
185
|
+
- 支付结果应该依赖服务端的异步通知,客户端返回仅作为支付结束的通知
|
|
186
|
+
|
|
187
|
+
```js
|
|
188
|
+
import * as Alipay from 'expo-alipay-sdk';
|
|
189
|
+
|
|
190
|
+
// orderInfo 应该从服务端获取
|
|
191
|
+
const orderInfo = await fetchOrderInfoFromServer();
|
|
192
|
+
Alipay.pay(orderInfo).then((result) => {
|
|
193
|
+
console.log('支付成功:', result);
|
|
194
|
+
}).catch((error) => {
|
|
195
|
+
console.log('支付失败:', error);
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### getVersion() 获取 SDK 版本号
|
|
200
|
+
|
|
201
|
+
- returns {Promise<String>} SDK 版本号
|
|
202
|
+
|
|
203
|
+
```js
|
|
204
|
+
import * as Alipay from 'expo-alipay-sdk';
|
|
205
|
+
|
|
206
|
+
Alipay.getVersion().then((version) => {
|
|
207
|
+
console.log('SDK 版本:', version);
|
|
208
|
+
});
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### isAlipayInstalled() 判断支付宝是否已安装
|
|
212
|
+
|
|
213
|
+
- returns {Promise<Boolean>} 支付宝是否已安装
|
|
214
|
+
|
|
215
|
+
```js
|
|
216
|
+
import * as Alipay from 'expo-alipay-sdk';
|
|
217
|
+
|
|
218
|
+
Alipay.isAlipayInstalled().then((installed) => {
|
|
219
|
+
if (installed) {
|
|
220
|
+
console.log('支付宝已安装');
|
|
221
|
+
} else {
|
|
222
|
+
console.log('支付宝未安装');
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## 支付结果状态码说明
|
|
228
|
+
|
|
229
|
+
| 状态码 | 说明 |
|
|
230
|
+
|--------|------|
|
|
231
|
+
| 9000 | 订单支付成功 |
|
|
232
|
+
| 8000 | 正在处理中,支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态 |
|
|
233
|
+
| 4000 | 订单支付失败 |
|
|
234
|
+
| 5000 | 重复请求 |
|
|
235
|
+
| 6001 | 用户中途取消 |
|
|
236
|
+
| 6002 | 网络连接出错 |
|
|
237
|
+
| 6004 | 支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态 |
|
|
238
|
+
| 其它 | 其它支付错误 |
|
|
239
|
+
|
|
240
|
+
## 注意事项
|
|
241
|
+
|
|
242
|
+
1. **签名安全**:支付参数签名过程和私钥 **必须在 App 服务端** 完成,严禁放在客户端
|
|
243
|
+
2. **测试环境**:接入后请对设备上 **已安装支付宝 App** 和 **未安装支付宝 App** 两种情况分别测试支付流程
|
|
244
|
+
3. **支付结果验证**:客户端返回的支付结果仅作为支付结束的通知,真实的支付结果需要依赖服务端的异步通知
|
|
245
|
+
4. **iOS 配置**:确保在 `app.json` 中正确配置了 URL Scheme,且与支付宝开放平台配置一致(插件会自动应用到 `Info.plist`)
|
|
246
|
+
|
|
247
|
+
## 常见问题
|
|
248
|
+
|
|
249
|
+
### iOS 支付回调无法接收
|
|
250
|
+
|
|
251
|
+
1. 检查 `app.json` 中的 `ios.infoPlist.CFBundleURLSchemes` 是否配置正确
|
|
252
|
+
2. 确保 URL Scheme 与支付宝开放平台配置一致
|
|
253
|
+
3. 检查 `app.json` 中的 `ios.infoPlist.LSApplicationQueriesSchemes` 是否包含 `alipay` 和 `alipays`
|
|
254
|
+
4. 运行 `npx expo prebuild --clean` 重新生成原生项目
|
|
255
|
+
|
|
256
|
+
### Android 支付失败
|
|
257
|
+
|
|
258
|
+
1. 检查 `app.json` 中的 `android.package` 是否配置正确
|
|
259
|
+
2. 插件会自动添加 ProGuard 混淆规则和权限配置
|
|
260
|
+
3. 运行 `npx expo prebuild --clean` 重新生成原生项目
|
|
261
|
+
|
|
262
|
+
### 支付结果状态码为 4000
|
|
263
|
+
|
|
264
|
+
- 检查订单信息是否正确
|
|
265
|
+
- 检查签名是否正确
|
|
266
|
+
- 检查 AppID 是否匹配
|
|
267
|
+
|
|
268
|
+
## 版本更新说明
|
|
269
|
+
|
|
270
|
+
本包基于支付宝官方 SDK 15.8.40 版本开发。
|
|
271
|
+
|
|
272
|
+
## License
|
|
273
|
+
|
|
274
|
+
MIT
|
|
275
|
+
|
|
276
|
+
## 相关链接
|
|
277
|
+
|
|
278
|
+
- [支付宝开放平台](https://open.alipay.com/)
|
|
279
|
+
- [支付宝 App 支付文档](https://opendocs.alipay.com/open/204/105296)
|
|
280
|
+
- [问题反馈](https://github.com/your-username/expo-alipay/issues)
|
|
281
|
+
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// android/build.gradle
|
|
2
|
+
// 这些默认值应该反映 React Native 最低支持版本使用的 SDK 版本
|
|
3
|
+
|
|
4
|
+
apply plugin: 'com.android.library'
|
|
5
|
+
|
|
6
|
+
// 安全获取扩展属性,如果不存在则使用默认值
|
|
7
|
+
def safeExtGet(prop, fallback) {
|
|
8
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
android {
|
|
12
|
+
// 编译 SDK 版本,默认使用 31
|
|
13
|
+
compileSdkVersion safeExtGet('compileSdkVersion', 31)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
dependencies {
|
|
17
|
+
// 忽略 Gradle 动态版本警告
|
|
18
|
+
// noinspection GradleDynamicVersion
|
|
19
|
+
implementation 'com.facebook.react:react-native:+' // 从 node_modules 引入
|
|
20
|
+
api 'com.alipay.sdk:alipaysdk-android:+@aar' // 支付宝 SDK
|
|
21
|
+
}
|
|
22
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!-- AndroidManifest.xml -->
|
|
2
|
+
|
|
3
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
4
|
+
package="com.goldstar.alipay">
|
|
5
|
+
<uses-permission android:name="android.permission.INTERNET"/>
|
|
6
|
+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
|
7
|
+
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
|
8
|
+
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
|
9
|
+
|
|
10
|
+
<queries>
|
|
11
|
+
<package android:name="com.eg.android.AlipayGphone" />
|
|
12
|
+
</queries>
|
|
13
|
+
</manifest>
|
|
14
|
+
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// AlipayModule.java
|
|
2
|
+
|
|
3
|
+
package com.goldstar.alipay;
|
|
4
|
+
|
|
5
|
+
import android.app.Activity;
|
|
6
|
+
import android.content.Intent;
|
|
7
|
+
import android.os.Handler;
|
|
8
|
+
import android.os.Message;
|
|
9
|
+
import android.text.TextUtils;
|
|
10
|
+
import android.util.Log;
|
|
11
|
+
import com.alipay.sdk.app.PayTask;
|
|
12
|
+
import com.facebook.react.bridge.ActivityEventListener;
|
|
13
|
+
import com.facebook.react.bridge.Arguments;
|
|
14
|
+
import com.facebook.react.bridge.BaseActivityEventListener;
|
|
15
|
+
import com.facebook.react.bridge.Promise;
|
|
16
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
17
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
18
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
19
|
+
import com.facebook.react.bridge.WritableMap;
|
|
20
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
21
|
+
import java.util.Map;
|
|
22
|
+
|
|
23
|
+
public class AlipayModule extends ReactContextBaseJavaModule {
|
|
24
|
+
private static final String MODULE_NAME = "Alipay";
|
|
25
|
+
private static final int SDK_PAY_FLAG = 1;
|
|
26
|
+
private String appId;
|
|
27
|
+
private ReactApplicationContext reactContext;
|
|
28
|
+
private static final String NOT_REGISTERED = "registerApp required.";
|
|
29
|
+
|
|
30
|
+
private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {
|
|
31
|
+
@Override
|
|
32
|
+
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent intent) {
|
|
33
|
+
// 支付宝支付结果通过 PayResult 回调处理,这里不需要处理
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
public AlipayModule(ReactApplicationContext reactContext) {
|
|
38
|
+
super(reactContext);
|
|
39
|
+
this.reactContext = reactContext;
|
|
40
|
+
reactContext.addActivityEventListener(mActivityEventListener);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@Override
|
|
44
|
+
public String getName() {
|
|
45
|
+
return MODULE_NAME;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@ReactMethod
|
|
49
|
+
public void registerApp(String appId, String universalLink, Promise promise) {
|
|
50
|
+
this.appId = appId;
|
|
51
|
+
promise.resolve(true);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@ReactMethod
|
|
55
|
+
public void pay(String orderInfo, Promise promise) {
|
|
56
|
+
if (TextUtils.isEmpty(orderInfo)) {
|
|
57
|
+
promise.reject("INVALID_PARAM", "orderInfo cannot be empty");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
final Activity currentActivity = getCurrentActivity();
|
|
61
|
+
if (currentActivity == null) {
|
|
62
|
+
promise.reject("NO_ACTIVITY", "Current activity is null");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
final Handler mHandler = new Handler() {
|
|
66
|
+
@SuppressWarnings("unchecked")
|
|
67
|
+
public void handleMessage(Message msg) {
|
|
68
|
+
switch (msg.what) {
|
|
69
|
+
case SDK_PAY_FLAG: {
|
|
70
|
+
PayResult payResult = new PayResult((Map<String, String>) msg.obj);
|
|
71
|
+
String resultStatus = payResult.getResultStatus();
|
|
72
|
+
WritableMap resultMap = Arguments.createMap();
|
|
73
|
+
resultMap.putString("resultStatus", resultStatus);
|
|
74
|
+
resultMap.putString("result", payResult.getResult());
|
|
75
|
+
resultMap.putString("memo", payResult.getMemo());
|
|
76
|
+
resultMap.putString("type", "PayResult.Resp");
|
|
77
|
+
reactContext
|
|
78
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
79
|
+
.emit("Alipay_Resp", resultMap);
|
|
80
|
+
if (TextUtils.equals(resultStatus, "9000")) {
|
|
81
|
+
promise.resolve(resultMap);
|
|
82
|
+
} else {
|
|
83
|
+
promise.reject(resultStatus, payResult.getMemo(), null);
|
|
84
|
+
}
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
default:
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
Runnable payRunnable = new Runnable() {
|
|
93
|
+
@Override
|
|
94
|
+
public void run() {
|
|
95
|
+
PayTask alipay = new PayTask(currentActivity);
|
|
96
|
+
Map<String, String> result = alipay.payV2(orderInfo, true);
|
|
97
|
+
Log.i("Alipay", result.toString());
|
|
98
|
+
Message msg = new Message();
|
|
99
|
+
msg.what = SDK_PAY_FLAG;
|
|
100
|
+
msg.obj = result;
|
|
101
|
+
mHandler.sendMessage(msg);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
Thread payThread = new Thread(payRunnable);
|
|
105
|
+
payThread.start();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@ReactMethod
|
|
109
|
+
public void getVersion(Promise promise) {
|
|
110
|
+
try {
|
|
111
|
+
Activity currentActivity = getCurrentActivity();
|
|
112
|
+
if (currentActivity == null) {
|
|
113
|
+
promise.reject("NO_ACTIVITY", "Current activity is null");
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
PayTask payTask = new PayTask(currentActivity);
|
|
117
|
+
String version = payTask.getVersion();
|
|
118
|
+
promise.resolve(version);
|
|
119
|
+
} catch (Exception e) {
|
|
120
|
+
promise.reject("ERROR", e.getMessage());
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@ReactMethod
|
|
125
|
+
public void isAlipayInstalled(Promise promise) {
|
|
126
|
+
try {
|
|
127
|
+
Activity currentActivity = getCurrentActivity();
|
|
128
|
+
if (currentActivity == null) {
|
|
129
|
+
promise.reject("NO_ACTIVITY", "Current activity is null");
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
PayTask payTask = new PayTask(currentActivity);
|
|
133
|
+
boolean isInstalled = payTask.isAliPayInstalled();
|
|
134
|
+
promise.resolve(isInstalled);
|
|
135
|
+
} catch (Exception e) {
|
|
136
|
+
promise.reject("ERROR", e.getMessage());
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// AlipayPackage.java
|
|
2
|
+
|
|
3
|
+
package com.goldstar.alipay;
|
|
4
|
+
|
|
5
|
+
import com.facebook.react.ReactPackage;
|
|
6
|
+
import com.facebook.react.bridge.NativeModule;
|
|
7
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
8
|
+
import com.facebook.react.uimanager.ViewManager;
|
|
9
|
+
import java.util.ArrayList;
|
|
10
|
+
import java.util.Collections;
|
|
11
|
+
import java.util.List;
|
|
12
|
+
|
|
13
|
+
public class AlipayPackage implements ReactPackage {
|
|
14
|
+
@Override
|
|
15
|
+
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
|
16
|
+
return Collections.emptyList();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@Override
|
|
20
|
+
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
|
21
|
+
List<NativeModule> modules = new ArrayList<>();
|
|
22
|
+
modules.add(new AlipayModule(reactContext));
|
|
23
|
+
return modules;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// PayResult.java
|
|
2
|
+
|
|
3
|
+
package com.goldstar.alipay;
|
|
4
|
+
|
|
5
|
+
import android.text.TextUtils;
|
|
6
|
+
import java.util.Map;
|
|
7
|
+
|
|
8
|
+
public class PayResult {
|
|
9
|
+
private String resultStatus;
|
|
10
|
+
private String result;
|
|
11
|
+
private String memo;
|
|
12
|
+
|
|
13
|
+
public PayResult(Map<String, String> rawResult) {
|
|
14
|
+
if (rawResult == null) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
for (String key : rawResult.keySet()) {
|
|
18
|
+
if (TextUtils.equals(key, "resultStatus")) {
|
|
19
|
+
resultStatus = rawResult.get(key);
|
|
20
|
+
} else if (TextUtils.equals(key, "result")) {
|
|
21
|
+
result = rawResult.get(key);
|
|
22
|
+
} else if (TextUtils.equals(key, "memo")) {
|
|
23
|
+
memo = rawResult.get(key);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@Override
|
|
29
|
+
public String toString() {
|
|
30
|
+
return "resultStatus={" + resultStatus + "};memo={" + memo
|
|
31
|
+
+ "};result={" + result + "}";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public String getResultStatus() {
|
|
35
|
+
return resultStatus;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public String getMemo() {
|
|
39
|
+
return memo;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public String getResult() {
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
package/app.plugin.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Expo 配置插件 - 支付宝 SDK
|
|
2
|
+
const { withInfoPlist, withAndroidManifest, withDangerousMod } = require('@expo/config-plugins');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
// ProGuard 混淆规则
|
|
8
|
+
const PROGUARD_RULES = '# 支付宝 SDK 混淆规则\n-keep class com.alipay.** {\n *;\n}\n\n-dontwarn com.alipay.**\n';
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
// 插件主函数
|
|
12
|
+
const withExpoAlipay = (config, props = {}) => {
|
|
13
|
+
config = withInfoPlist(config, (config) => {
|
|
14
|
+
return config;
|
|
15
|
+
});
|
|
16
|
+
config = withAndroidManifest(config, (config) => {
|
|
17
|
+
const packageName = config.android?.package || config.android?.packageName;
|
|
18
|
+
if (packageName && config.modResults.manifest) {
|
|
19
|
+
const manifest = config.modResults.manifest;
|
|
20
|
+
if (!manifest.application) {
|
|
21
|
+
manifest.application = [{}];
|
|
22
|
+
}
|
|
23
|
+
const mainApplication = manifest.application[0];
|
|
24
|
+
if (!mainApplication.activity) {
|
|
25
|
+
mainApplication.activity = [];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return config;
|
|
29
|
+
});
|
|
30
|
+
config = withDangerousMod(config, [
|
|
31
|
+
'android',
|
|
32
|
+
async (config) => {
|
|
33
|
+
const platformProjectRoot = config.modRequest.platformProjectRoot;
|
|
34
|
+
if (platformProjectRoot) {
|
|
35
|
+
const proguardRulesPath = path.join(platformProjectRoot, 'app', 'proguard-rules.pro');
|
|
36
|
+
let proguardContent = '';
|
|
37
|
+
if (fs.existsSync(proguardRulesPath)) {
|
|
38
|
+
proguardContent = fs.readFileSync(proguardRulesPath, 'utf-8');
|
|
39
|
+
}
|
|
40
|
+
if (!proguardContent.includes('com.alipay')) {
|
|
41
|
+
proguardContent += '\n' + PROGUARD_RULES;
|
|
42
|
+
fs.writeFileSync(proguardRulesPath, proguardContent, 'utf-8');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return config;
|
|
46
|
+
}
|
|
47
|
+
]);
|
|
48
|
+
return config;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
module.exports = withExpoAlipay;
|
|
53
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# expo-alipay.podspec
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
6
|
+
|
|
7
|
+
Pod::Spec.new do |s|
|
|
8
|
+
s.name = "expo-alipay"
|
|
9
|
+
s.version = package["version"]
|
|
10
|
+
s.summary = package["description"]
|
|
11
|
+
s.description = <<-DESC
|
|
12
|
+
为 Expo 和 React Native 提供支付宝支付功能的原生模块。
|
|
13
|
+
基于最新支付宝 SDK 开发,支持 iOS 和 Android 平台。
|
|
14
|
+
DESC
|
|
15
|
+
s.homepage = "https://github.com/your-username/expo-alipay"
|
|
16
|
+
s.license = "MIT"
|
|
17
|
+
s.authors = { "Your Name" => "your.email@example.com"}
|
|
18
|
+
s.platforms = { :ios => "9.0" }
|
|
19
|
+
s.source = { :git => "https://github.com/your-username/expo-alipay.git", :tag => "#{s.version}" }
|
|
20
|
+
s.source_files = "ios/**/*.{h,c,cc,cpp,m,mm,swift}"
|
|
21
|
+
s.requires_arc = true
|
|
22
|
+
s.dependency "React"
|
|
23
|
+
|
|
24
|
+
# 支付宝 SDK Framework - 自动引用 ios/iOS_SDK 目录
|
|
25
|
+
s.vendored_frameworks = "ios/iOS_SDK/AlipaySDK.framework"
|
|
26
|
+
s.resources = "ios/iOS_SDK/AlipaySDK.bundle"
|
|
27
|
+
|
|
28
|
+
# 系统框架依赖
|
|
29
|
+
s.frameworks = "CoreTelephony", "SystemConfiguration", "CoreMotion"
|
|
30
|
+
s.libraries = "c++", "z"
|
|
31
|
+
end
|
|
32
|
+
|