开发过支付宝、微信支付的同学都知道,微信的支付 API 设计感觉是 Java 开发工程师写的,远不如支付宝 SDK 的接口设计用起来顺手。在这里,统一封装微信支付和支付宝支付的API,使两种支付方式对外提供一致的调用接口。
首先我们来看支付宝支付SDK的API是怎么设计的:
/**
* 支付接口
*
* @param orderStr 支付订单信息字串
* @param schemeStr 调用支付的app注册在info.plist中的scheme
* @param completionBlock 支付结果回调Block,用于wap支付结果回调
跳转支付宝支付时只有当processOrderWithPaymentResult接口的completionBlock为nil时会使用这个bolock
*/
- (void)payOrder:(NSString *)orderStr
fromScheme:(NSString *)schemeStr
callback:(CompletionBlock)completionBlock;
支付宝SDK的设计十分简洁,只有三个参数,分别负责:1.支付信息 2.进程跳转的 scheme 3.支付结果回调 block。
然后看一下微信支付的API:
/*! @brief 发送请求到微信,等待微信返回onResp
*
* 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持以下类型
* SendAuthReq、SendMessageToWXReq、PayReq等。
* @param req 具体的发送请求,在调用函数后,请自己释放。
* @return 成功返回YES,失败返回NO。
*/
+ (BOOL)sendReq:(BaseReq*)req;
/*! @brief 处理微信通过URL启动App时传递的数据
*
* 需要在 application:openURL:sourceApplication:annotation:或者application:handleOpenURL中调用。
* @param url 微信启动第三方应用时传递过来的URL
* @param delegate WXApiDelegate对象,用来接收微信触发的消息。
* @return 成功返回YES,失败返回NO。
*/
+ (BOOL)handleOpenURL:(NSURL *)url delegate:(nullable id<WXApiDelegate>)delegate;
要发起微信支付,首先要实例化 一个PayReq
对象,接着将这个对象的6个字段分别赋值,然后发起支付请求,等从微信返回到APP后,再从代理方法获取支付结果。相比支付宝SDK提供的接口,要繁琐了不少,可见接口设计是多么的重要,(当然支付宝的入参是事先拼接好的,拼接工作可以移交给后端)。
我们希望不管是微信支付还是支付宝支付,都能有统一风格的调用接口,方便逻辑复用,那么接下来的工作就是通过封装 使这这两者的接口统一。
在这里,我们设想的接口是:
- 只有一个入参,组织参数的方式尽量简单
- 回调直接给出结果
以下是设计的接口:
typedef void(^PayResult)(PayResponse *result);
typedef void(^wxShareCallback)(int resp);
@interface PaymentHub : NSObject<WXApiDelegate>
/**
获取 单利
@return 返回单利实例
*/
+ (instancetype)hub;
/**
支付宝支付
@param orderStr 支付订单加密信息
@param callback 支付结果回调
*/
- (void)AlipayWithOrder:(NSString *)orderStr callback:(PayResult)callback;
/**
微信支付
@param request 微信支付所需参数
@param callback 支付结果回调
*/
- (void)WXpayWithRequest:(PayReq *)request callback:(PayResult)callback;
/**
进程间通信处理
@param url 进程间 交换的数据
@param callback 微信分享回调
*/
- (void)handleOpenUrl:(NSURL *)url response:(wxShareCallback)callback;
+ (PayReq *)fromMap:(NSDictionary *)dict;
为了方便组织微信支付所需的字段,fromMap
方法可以将包含数据的字典转换为 一个PayReq
实例对象。在封装里,将微信SDK的 代理指定为 PaymentHub
的实例,在实例内部处理微信的代理回调。
考虑到微信SDK还可能会负责分享,在handleOpenUrl
方法里需要做区分处理。