PayPlugin
概述
目前支持的支付方式有
- 支付宝
- 微信
- 银联
- 一网通
- 银联充值
- 钱包
准备工作
-
若想在 App 中打开第三方 App,就需要在 info.plist 文件中完成参数配置:[查看图片](https://raw.githubusercontent.com/wufeiyue/PayPlugin/master/Resources/openURL@2x.png)
-
要从第三方 App 中跳回到我们的 App 中,就需要在
URL Type
中添加我们 App 的 Scheme,例如,支付宝在返回商户时,需要根据 Scheme 唤醒我们的 App,因此这里需要在 info 中配置,如下图所示:[查看图片](https://raw.githubusercontent.com/wufeiyue/PayPlugin/master/Resources/info@2x.png)
配置
1.支付配置仅暴露一个接口
/// 发起支付
///
/// - Parameters:
/// - target: 用于承载跳转的视图控制器
/// - provider: 提供支付签名的配置类
/// - result: 支付结果
func pay<T: PayBaseCustomizer>(target: UIViewController, provider: T, result: @escaping (PayResult<T.Model>) -> Void)
2.用于 AppDelegate 中通知支付结果的 OpenURL 调用
/// 通知支付结果
///
/// - Parameter url: 第三方客户端回传过来的URL地址
func sendNotification(_ url: URL)
演示
1.在 ViewController 中引用实例,支付结果在 .success(let model) 中回调,其中 model 为接口 query(dict: _, payResult: _) 调用后,返回的网络请求结果解析的 Model 类型,例如 model 为下面 AlipayModel 的实例:
func viewDidLoad() {
let provider = AlipayProvider()
PayPlugin.default.pay(target: self, provider: provider) { (result) in
switch result {
case .success(let status):
echo("支付成功:\(status)👍")
case .progress(let progress):
echo("当前进度:\(progress)")
switch progress {
case .prepare:
//显示loading视图
showLoading()
case .completed:
//隐藏loading视图
hideLoading()
}
case .failure(let error):
echo(error.localizedDescription)
}
}
}
2. 新增一个支付签名配置的类,需要遵守PayProviderCustomizer
协议,其中需要实现的方法如下
struct AlipayModel {
var amount: Double = 0.0
var isPaySuccess: Bool = false
}
class AlipayProvider: PayProviderCustomizer {
//验签接口解析成的数据模型, 完全自定义
typealias Model = AlipayModel
//配置的支付类型, 依据此PayType会自动匹配SDK中支付宝支付相关的API
var payType: PayType {
//这里填入我们的App的scheme, 便于从支付宝跳回到我们的App中
return .alipay(scheme: "wmdl")
}
//签名配置类, 将签名结果回传给SDK中处理, 切记无论成功或失败都需要回传过去
func sign(result: @escaping (ResponseResult<PayParamsType>) -> Void) {
Alamofire.request(url: "https://****/alipay/sign", successCompletion: { dict in
if let orderInfo = dict["orderInfo"] as? String {
result(.success(.client(orderInfo: orderInfo)))
return
}
result(.failure(.signFailure))
}) { (error) in
echo("请求失败: \(error)")
result(.failure(.responseFailure))
}
}
//验签接口配置, 如果dict为空, 就需要请求服务器去查询结果了, 一般不为空, dict为调用支付宝SDK验签接口返回的数据, 需保证Appdelegate中有配置, 此方法才会被调用
func query(dict: [AnyHashable : Any?]?, payResult: @escaping (ResponseResult<Int>) -> Void) {
Alamofire.request(url: "https://****/alipay/syncResult", successCompletion: {
let model = AlipayModel(amount: $0.0, isPaySuccess: $0.1)
payResult(.success(model))
}) { (error) in
echo("请求失败: \(error)")
payResult(.failure(.signFailure))
}
}
}
2. 在Appdelegate中完成配置
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return openURLHandle(url: url)
}
// ios 9
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return openURLHandle(url: url, options: options)
}
func openURLHandle(url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
PayPlugin.default.sendNotification(url)
return true
}
安装
在项目中使用 pod install
命令安装即可
pod 'PayPlugin'
说明
当发起支付宝/微信支付后,从我们的App跳转到支付平台(支付宝/微信),然后不进行支付操作,直接切回到我们的App是没有查询支付结果query方法的调用的,我参考摩拜单车它们也没有处理。这里先留个疑问。如果进行支付,并且支付成功后,支付宝会直接跳回到我们的App中,这样没有问题,但微信和建行它们都需要点击返回商户
按钮才能回来,那这时如果支付完成,不点击按钮,直接切回到我们的App,也是不进行query方法查询的。那么App就无法得知当前支付结果的状态,是成功还是失败。摩拜它们是只要App从后台切到前台都会刷新一次接口,可以查询到支付结果的状态也就不存在什么问题了,采用这种方式也行。所以后期我会改下机制。就是在发起支付后,整个生命周期内,如果检测到App从后台切回前台,都会调用一次query方法,去查询支付结果反馈到页面。当然这也不是必须的,我会给出一个调用策略。
作者
@wufeiyue,有问题请在主页上提issue,谢谢使用。
证书认证
Component_Pay适用于MIT许可协议。有关更多信息,请参阅LICENSE文件。