← API | 列表 | swift_SDK微信与支付宝
提示信息
# 同伴 App — 微信 SDK + 支付宝 SDK 接入

> 微信:登录 + 分享 + 支付 | 支付宝:App 支付

---

## 一、微信 SDK(WechatOpenSDK-XCFramework)

### 1.1 配置参数

| 参数 | 值 |
|------|-----|
| App ID | `wx146a6f748a99a0da` |
| Universal Link | `https://www.tongban.wang/app/` |
| Pod | `WechatOpenSDK-XCFramework`, `~> 2.0` |

### 1.2 Info.plist 配置

```xml
<!-- URL Schemes -->
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>wx146a6f748a99a0da</string>
        </array>
        <key>CFBundleURLName</key>
        <string>weixin</string>
    </dict>
</array>

<!-- LSApplicationQueriesSchemes -->
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>weixin</string>
    <string>wechat</string>
    <string>weixinULAPI</string>
</array>
```

### 1.3 Associated Domains

Xcode → Signing & Capabilities → Associated Domains:

```
applinks:www.tongban.wang
```

### 1.4 SDK 注册(AppDelegate)

```swift
import WechatOpenSDK

// didFinishLaunchingWithOptions 中注册
WXApi.registerApp(
    AppConfig.wechatAppId,
    universalLink: AppConfig.wechatUniversalLink
)
```

### 1.5 处理回调

```swift
// AppDelegate 或 SceneDelegate
func application(
    _ app: UIApplication,
    open url: URL,
    options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
    if url.scheme == AppConfig.wechatAppId {
        return WXApi.handleOpen(url, delegate: WechatManager.shared)
    }
    return false
}

// Universal Link 回调
func application(
    _ application: UIApplication,
    continue userActivity: NSUserActivity,
    restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
    return WXApi.handleOpenUniversalLink(userActivity, delegate: WechatManager.shared)
}
```

### 1.6 微信登录

```swift
// WechatManager.swift
final class WechatManager: NSObject {
    static let shared = WechatManager()

    private var loginContinuation: CheckedContinuation<String, Error>?

    /// 发起微信授权登录,返回 code
    func requestLogin() async throws -> String {
        guard WXApi.isWXAppInstalled() else {
            throw AppAPIError(code: -1, message: "未安装微信")
        }
        return try await withCheckedThrowingContinuation { continuation in
            self.loginContinuation = continuation
            let req = SendAuthReq()
            req.scope = "snsapi_userinfo"
            req.state = UUID().uuidString
            WXApi.send(req)
        }
    }
}

extension WechatManager: WXApiDelegate {
    func onResp(_ resp: BaseResp) {
        if let authResp = resp as? SendAuthResp {
            if authResp.errCode == 0, let code = authResp.code {
                loginContinuation?.resume(returning: code)
            } else {
                loginContinuation?.resume(throwing: AppAPIError(
                    code: Int(authResp.errCode),
                    message: authResp.errStr ?? "微信授权失败"
                ))
            }
            loginContinuation = nil
        }
    }
}
```

### 1.7 微信支付

```swift
extension WechatManager {
    /// 发起微信支付
    /// 参数从服务端 /pay/wechat/create 接口返回
    func pay(
        partnerId: String,
        prepayId: String,
        nonceStr: String,
        timeStamp: UInt32,
        package: String,
        sign: String
    ) async throws {
        return try await withCheckedThrowingContinuation { continuation in
            let req = PayReq()
            req.partnerId = partnerId
            req.prepayId  = prepayId
            req.nonceStr  = nonceStr
            req.timeStamp = timeStamp
            req.package   = package
            req.sign      = sign
            // 存储 continuation 并发送请求
            self.payContinuation = continuation
            WXApi.send(req)
        }
    }
}
```

---

## 二、支付宝 SDK(AlipaySDK_No_UTDID)

### 2.1 配置参数

| 参数 | 值 |
|------|-----|
| URL Scheme | `tongban` |
| Pod | `AlipaySDK_No_UTDID`(避免 UTDID 冲突) |

### 2.2 Info.plist 配置

```xml
<!-- URL Schemes -->
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>tongban</string>
        </array>
        <key>CFBundleURLName</key>
        <string>alipay</string>
    </dict>
</array>

<!-- LSApplicationQueriesSchemes -->
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>alipay</string>
    <string>alipays</string>
</array>
```

### 2.3 发起支付

```swift
// PaymentAdapter.swift
import AlipaySDK

enum PaymentAdapter {

    /// 支付宝 App 支付
    /// orderString 由服务端 /pay/alipay/create 接口返回(已签名)
    static func alipay(orderString: String) async throws {
        return try await withCheckedThrowingContinuation { continuation in
            AlipaySDK.defaultService().payOrder(
                orderString,
                fromScheme: "tongban"
            ) { result in
                guard let dict = result as? [String: Any],
                      let status = dict["resultStatus"] as? String else {
                    continuation.resume(throwing: AppAPIError(code: -1, message: "支付宝返回异常"))
                    return
                }
                switch status {
                case "9000":  // 支付成功
                    continuation.resume()
                case "6001":  // 用户取消
                    continuation.resume(throwing: AppAPIError(code: 6001, message: "用户取消支付"))
                case "4000":  // 支付失败
                    continuation.resume(throwing: AppAPIError(code: 4000, message: "支付失败"))
                default:
                    let msg = dict["memo"] as? String ?? "支付异常"
                    continuation.resume(throwing: AppAPIError(code: Int(status) ?? -1, message: msg))
                }
            }
        }
    }
}
```

### 2.4 处理回调

```swift
// AppDelegate 或 SceneDelegate
func application(
    _ app: UIApplication,
    open url: URL,
    options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
    if url.scheme == "tongban" {
        AlipaySDK.defaultService().processOrder(
            withPaymentResult: url
        ) { result in
            // 支付结果已在 payOrder 回调中处理
        }
        return true
    }
    return false
}
```

### 2.5 支付宝结果状态码

| resultStatus | 含义 |
|--------------|------|
| `9000` | 支付成功 |
| `8000` | 正在处理中(支付结果未知,需查询) |
| `4000` | 支付失败 |
| `5000` | 重复请求 |
| `6001` | 用户取消 |
| `6002` | 网络连接出错 |
| `6004` | 支付结果未知(需查询) |

---

## 三、统一支付入口

```swift
// PaymentAdapter.swift — 统一支付入口
extension PaymentAdapter {

    enum PaymentMethod {
        case wechat
        case alipay
    }

    /// 统一支付入口
    /// 1. 调用服务端创建订单
    /// 2. 根据支付方式调用对应 SDK
    static func pay(
        orderId: String,
        method: PaymentMethod
    ) async throws {
        switch method {
        case .wechat:
            // 服务端返回微信支付参数
            let params: [String: Any] = try await APIClient.shared.post(
                "/pay/wechat/create",
                body: ["order_id": orderId]
            )
            try await WechatManager.shared.pay(
                partnerId: params["partnerId"] as? String ?? "",
                prepayId:  params["prepayId"]  as? String ?? "",
                nonceStr:  params["nonceStr"]  as? String ?? "",
                timeStamp: params["timeStamp"] as? UInt32 ?? 0,
                package:   params["package"]   as? String ?? "",
                sign:      params["sign"]      as? String ?? ""
            )

        case .alipay:
            // 服务端返回支付宝签名字符串
            let result: [String: Any] = try await APIClient.shared.post(
                "/pay/alipay/create",
                body: ["order_id": orderId]
            )
            let orderString = result["order_string"] as? String ?? ""
            try await alipay(orderString: orderString)
        }
    }
}
```