# expo-alipay

专为 Expo 打造的支付宝支付集成解决方案。
更新于2025年12月。
基于最新支付宝官方 SDK 开发，支持 iOS 和 Android 双平台，为 Expo 项目提供稳定可靠的支付宝支付功能支持：

- ✅ **支付宝支付** - 完整的支付功能集成

## 前期准备

在开始使用本库之前，请确保你已经准备好以下内容：

### 必需配置

1. **支付宝 AppID**
   - 在 [支付宝开放平台](https://open.alipay.com/) 注册并创建移动应用
   - 获取应用的 **AppID**
   - 完成应用的基本信息填写和审核

2. **iOS URL Scheme 配置**（仅 iOS 需要）
   - 为什么需要：iOS 系统需要通过 URL Scheme 来实现应用间的跳转和回调。如果不配置，将导致：
     - ❌ 无法接收支付回调
   - 详细配置步骤请参考下方配置说明

### 支付功能额外配置

如果你需要使用支付宝支付功能，还需要额外准备：

- **商户私钥** - 用于签名验证（**必须在服务端完成，严禁放在客户端**）
- **支付宝公钥** - 用于验证支付结果

> 💡 **重要提示**：支付参数签名过程和私钥 **必须在 App 服务端** 完成，示例项目中的签名流程仅供开发时参考。严禁将私钥放在客户端，否则可能造成资金损失和安全风险。

## 快速开始（0 配置）

本包采用 0 配置设计，安装后只需配置 `app.json` 即可使用，所有 SDK 文件和原生配置都会自动处理。

```bash
npx expo install expo-alipay-sdk
```

或

```bash
yarn add expo-alipay-sdk
```

## 配置步骤

### 1. 安装插件

```bash
npx expo install expo-alipay-sdk
```

或

```bash
yarn add expo-alipay-sdk
```

### 2. 配置 app.json

在项目根目录的 `app.json` 或 `app.config.js` 中添加插件配置：

```json
{
  "expo": {
    "plugins": [
      "expo-alipay-sdk"
    ],
    "ios": {
      "infoPlist": {
        "LSApplicationQueriesSchemes": ["alipay", "alipays"],
        "CFBundleURLTypes": [
          {
            "CFBundleTypeRole": "Editor",
            "CFBundleURLName": "alipay",
            "CFBundleURLSchemes": ["你的AppScheme"]
          }
        ]
      }
    },
    "android": {
      "package": "com.your.package.name"
    }
  }
}
```

**重要说明：**
- 将 `你的AppScheme` 替换为你在支付宝开放平台配置的实际 URL Scheme
- `android.package` 需要设置为你的应用包名
- iOS 的 `CFBundleURLSchemes` 必须与支付宝开放平台配置的 URL Scheme 一致

### 3. 执行预构建

运行以下命令生成原生项目：

```bash
npx expo prebuild
```

**就这么简单！** 插件会自动完成所有配置：

#### 自动配置功能
- ✅ **iOS SDK 自动集成**：自动配置支付宝 iOS SDK Framework 和 Bundle
- ✅ **Android SDK 自动依赖**：自动添加支付宝 Android SDK Maven 依赖
- ✅ **ProGuard 混淆规则**：自动添加支付宝 SDK 的混淆规则，防止代码混淆导致的功能异常
- ✅ **Android 11+ 兼容**：自动添加 `<queries>` 标签，确保在 Android 11 及以上版本正常使用
- ✅ **iOS URL Scheme**：自动配置 URL Schemes 和查询方案

> ⚠️ **重要提示**：不建议手动修改原生项目配置文件（如 `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)。

## 调用库

```javascript
import * as Alipay from 'expo-alipay-sdk';

// 注册应用
Alipay.registerApp('你的AppID', '你的UniversalLink（可选）').then((result) => {
    console.log("注册成功:", result);
});

// 发起支付
const orderInfo = "你的订单信息字符串（由服务端生成并签名）";
Alipay.pay(orderInfo).then((result) => {
    console.log("支付成功:", result);
}).catch((error) => {
    console.log("支付失败:", error);
});
```

## 回调事件订阅

支付完成后会触发回调事件，请在调用支付方法前提前添加事件监听。

```js
import { DeviceEventEmitter } from 'react-native';
import * as Alipay from 'expo-alipay-sdk';

// 注册应用
Alipay.registerApp('your_app_id', 'your_universal_link');

// 监听支付回调
DeviceEventEmitter.addListener('Alipay_Resp', resp => {
  console.log('支付宝回调:', resp);
  
  if (resp.type === 'PayResult.Resp') {
    // 支付回调
    if (resp.resultStatus === '9000') {
      console.log('支付成功');
    } else {
      console.log('支付失败:', resp.memo);
    }
  }
});
```

## API 文档

本库支持 `TypeScript`，使用 `Promise` 或 `async/await` 来接收返回。

### registerApp(appId, universalLink?) 注册应用

- `appId` {String} 支付宝应用 ID
- `universalLink` {String} iOS Universal Link（可选，仅 iOS 需要）
- returns {Promise<Boolean>} 注册是否成功

此方法应该在应用启动时全局调用一次。

```js
import * as Alipay from 'expo-alipay-sdk';

Alipay.registerApp('your_app_id', 'your_universal_link');
```

### pay(orderInfo) 发起支付

- `orderInfo` {String} 支付订单信息字符串（由服务端生成并签名）
- returns {Promise<PayResult>} 支付结果

**重要说明：**
- `orderInfo` 必须由服务端生成并签名，严禁在客户端进行签名操作
- 支付结果应该依赖服务端的异步通知，客户端返回仅作为支付结束的通知

```js
import * as Alipay from 'expo-alipay-sdk';

// orderInfo 应该从服务端获取
const orderInfo = await fetchOrderInfoFromServer();
Alipay.pay(orderInfo).then((result) => {
    console.log('支付成功:', result);
}).catch((error) => {
    console.log('支付失败:', error);
});
```

### getVersion() 获取 SDK 版本号

- returns {Promise<String>} SDK 版本号

```js
import * as Alipay from 'expo-alipay-sdk';

Alipay.getVersion().then((version) => {
    console.log('SDK 版本:', version);
});
```

### isAlipayInstalled() 判断支付宝是否已安装

- returns {Promise<Boolean>} 支付宝是否已安装

```js
import * as Alipay from 'expo-alipay-sdk';

Alipay.isAlipayInstalled().then((installed) => {
    if (installed) {
        console.log('支付宝已安装');
    } else {
        console.log('支付宝未安装');
    }
});
```

## 支付结果状态码说明

| 状态码 | 说明 |
|--------|------|
| 9000 | 订单支付成功 |
| 8000 | 正在处理中，支付结果未知（有可能已经支付成功），请查询商户订单列表中订单的支付状态 |
| 4000 | 订单支付失败 |
| 5000 | 重复请求 |
| 6001 | 用户中途取消 |
| 6002 | 网络连接出错 |
| 6004 | 支付结果未知（有可能已经支付成功），请查询商户订单列表中订单的支付状态 |
| 其它 | 其它支付错误 |

## 注意事项

1. **签名安全**：支付参数签名过程和私钥 **必须在 App 服务端** 完成，严禁放在客户端
2. **测试环境**：接入后请对设备上 **已安装支付宝 App** 和 **未安装支付宝 App** 两种情况分别测试支付流程
3. **支付结果验证**：客户端返回的支付结果仅作为支付结束的通知，真实的支付结果需要依赖服务端的异步通知
4. **iOS 配置**：确保在 `app.json` 中正确配置了 URL Scheme，且与支付宝开放平台配置一致（插件会自动应用到 `Info.plist`）

## 常见问题

### iOS 支付回调无法接收

1. 检查 `app.json` 中的 `ios.infoPlist.CFBundleURLSchemes` 是否配置正确
2. 确保 URL Scheme 与支付宝开放平台配置一致
3. 检查 `app.json` 中的 `ios.infoPlist.LSApplicationQueriesSchemes` 是否包含 `alipay` 和 `alipays`
4. 运行 `npx expo prebuild --clean` 重新生成原生项目

### Android 支付失败

1. 检查 `app.json` 中的 `android.package` 是否配置正确
2. 插件会自动添加 ProGuard 混淆规则和权限配置
3. 运行 `npx expo prebuild --clean` 重新生成原生项目

### 支付结果状态码为 4000

- 检查订单信息是否正确
- 检查签名是否正确
- 检查 AppID 是否匹配

## 版本更新说明

本包基于支付宝官方 SDK 15.8.40 版本开发。

## License

MIT

## 相关链接

- [支付宝开放平台](https://open.alipay.com/)
- [支付宝 App 支付文档](https://opendocs.alipay.com/open/204/105296)
- [问题反馈](https://github.com/your-username/expo-alipay/issues)

