0%

iOS 集成微信支付 SDK

微信支付 SDK 版本:1.8.3

参考

  • 微信支付开发文档 ⭐️
  • 微信开放平台 - iOS 接入指南 ⭐️⭐️⭐️
  • 微信支付 APP 商户截图标准示范
  • 简书 - iOS - 微信支付总结
  • 简书 - 微信支付
  • 掘金 - iOS 微信支付接入以及工具类封装
  • GitHub:WXPay - 微信支付讲解示例 ⭐️⭐️⭐️

iOS 接入指南

讲解 iOS 接入微信 SDK,仅记录关键部分代码,其余在官方文档或网络文章中都已详述备尽,此处不再赘述。

1. 向微信注册你的应用程序 id

(略。。。)

2. 下载微信终端 SDK 文件

集成微信 SDK 有两种方式:

  1. 手动集成,下载 SDK 然后拖拽相关库文件到你的项目中;

  2. 通过 CocoaPods 集成:

    pod 'WechatOpenSDK', '~> 1.8.3'

3. 开发环境搭建

3.1 设置 TARGETS ,在 URL Types 中添加应用程序 id。

(略。。。)

3.2 设置微信白名单

在 Xcode 中,选择你的工程设置项,选中 “TARGETS” 一栏,在 “info” 标签栏的 “LSApplicationQueriesSchemes“添加 weixin:

weix

⚠️ 这个步骤用于判断微信是否安装([WXApi isWXAppInstalled]

详细可以参见 LSApplicationQueriesSchemes– 关于 info.plist 第三方登录 添加 URL Schemes 白名单

4. 在项目中添加代码

为了使项目代码更清晰简洁(解耦合思想),我创建了一个范畴(Category)类专门存放微信支付相关的代码:

4.1 AppDelegate+WechatPayService.h

#import "AppDelegate.h"

NS_ASSUME_NONNULL_BEGIN

/**
 集成微信支付
 */
@interface AppDelegate (WechatPayService)

// 配置方法,用于向微信终端注册应用 id
- (void)hql_configureForWechatPay;

@end

NS_ASSUME_NONNULL_END

4.2 AppDelegate+WechatPayService.m

#import "AppDelegate+WechatPayService.h"
#import <WechatOpenSDK/WXApi.h> // 引入微信 SDK

@interface AppDelegate () <WXApiDelegate> // 遵守 SDK 协议

@end

@implementation AppDelegate (WechatPayService)

#pragma mark - Public

- (void)hql_configureForWechatPay {
    //向微信注册
    //注:WechatAppId 是常量,已经写在了预编译配置文件中
    //#define WechatAppId @"wx12345...67890"
    [WXApi registerApp:WechatAppId];
}

#pragma mark - WeChatPay

// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options {
    return [WXApi handleOpenURL:url delegate:(id<WXApiDelegate>)self];
}

/*! @brief 发送一个sendReq后,收到微信的回应
 *
 * 收到一个来自微信的处理结果。调用一次sendReq后会收到onResp。
 * 可能收到的处理结果有SendMessageToWXResp、SendAuthResp等。
 * @param resp具体的回应内容,是自动释放的
 */
-(void) onResp:(BaseResp*)resp {
    // 微信支付成功/失败,发起通知查询
    // 注:HQLWechatPayOnResponceNotification 通知方法名是常量,统一写在配置文件中
    // #define HQLWechatPayOnResponceNotification @"HQLWechatPayOnResponceNotification"
    [[NSNotificationCenter defaultCenter] postNotificationName:HQLWechatPayOnResponceNotification
                                                        object:(BaseReq *)resp];
}

@end

4.3 AppDelegate.m

AppDelegate+WechatPayService 文件写好后,这里可以直接使用了。

#import "AppDelegate.h"
#import "AppDelegate+WechatPayService.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self hql_configureForWechatPay]; // 是的,只有一行配置代码
    return YES;
}

5. 发起微信支付代码

交互数据模型

先来看一下商户服务端返回的 JSON 数据格式:

{
    appid = "wx12345...678906"; (应用 ID)
    noncestr = "FS7JBpYQ5TzkyfcV"; (随机字符串)
    package = "Sign=WXPay"; (扩展字段,默认值)
    partnerid = "12345674321"; (商户号)
    prepayid = "wx2530149711249kd7b531c00a2446020522"; (预支付交易会话 ID)
    sign = "BEE9FA6FCD14D286CCCD4EE7DC74578B"; (签名)
    timestamp = 1545704053 (时间戳,精确到秒,10位!!!)
}

然后写一个模型类来映射 JSON 数据,如下,JSON 解析可以使用 YYModel 库。

HQLWechatPayRequestModel.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

/**
 微信支付,服务器返回支付参数模型
 */
@interface HQLWechatPayRequestModel : NSObject

/** 应用 ID */
@property (nonatomic, copy, readonly) NSString *appid;
/** 商家向财付通申请的商家 ID */
@property (nonatomic, copy, readonly) NSString *partnerid;
/** 预支付订单 */
@property (nonatomic, copy, readonly) NSString *prepayid;
/** 商家根据财付通文档填写的数据和签名,默认值为 Sign=WXPay */
@property (nonatomic, copy, readonly) NSString *package;
/** 随机串,防重发 */
@property (nonatomic, copy, readonly) NSString *noncestr;
/** 时间戳,防重发 */
@property (nonatomic, assign, readonly) UInt32 timestamp;
/** 商家根据微信开放平台文档对数据做的签名 */
@property (nonatomic, copy, readonly) NSString *sign;

@end

NS_ASSUME_NONNULL_END

HQLWechatPayRequestModel.m

#import "HQLWechatPayRequestModel.h"

@interface HQLWechatPayRequestModel ()

@property (nonatomic, copy, readwrite) NSString *appid;
@property (nonatomic, copy, readwrite) NSString *partnerid;
@property (nonatomic, copy, readwrite) NSString *prepayid;
@property (nonatomic, copy, readwrite) NSString *package;
@property (nonatomic, copy, readwrite) NSString *noncestr;
@property (nonatomic, assign, readwrite) UInt32 timestamp;
@property (nonatomic, copy, readwrite) NSString *sign;

@end

@implementation HQLWechatPayRequestModel

#pragma mark - NSObject

- (NSString *)description {
    return [self modelDescription];
}

@end

发起微信支付

#import "HQLWeChatPayViewController.h"

// Frameworks
#import <WechatOpenSDK/WXApi.h>
#import <WechatOpenSDK/WXApiObject.h>

// Models
#import "HQLWechatPayRequestModel.h"

@implementation HQLThirdPartyPayViewController

#pragma mark - Lifecycle

- (void)dealloc {
    // 移除微信支付通知
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    // 添加微信支付通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(respondsToWechatPayNotification:)
                                                 name:HQLWechatPayOnResponceNotification
                                               object:nil];
}

#pragma mark - Private

// 判断用户设备是否支持微信支付
- (BOOL)isSupportWechatPay {
    // 1.判断是否安装微信
    if (![WXApi isWXAppInstalled]) {
        // 业务代码,提示微信未安装...
        return NO;
    }
    // 2.判断微信的版本是否支持最新API
    if (![WXApi isWXAppSupportApi]) {
        // 业务代码,提示微信当前版本不支持此功能...
        return NO;
    }
    return YES;
}

// 响应微信支付回调通知
- (void)respondsToWechatPayNotification:(NSNotification *)notification {
    BaseResp *responds = notification.object;
    switch (responds.errCode) {
        case WXSuccess: {
            // 1. 微信支付成功
            // ...
            break;
        }
        case WXErrCodeCommon: {
            // 2. 微信支付失败
            // ...
            break;
        }
        case WXErrCodeUserCancel: {
            // 3. 用户点击取消并返回
            // ...
            break;
        }
        default: {
            break;
        }
    }
}

// 发起支付请求
- (void)dealWithOrderPay {
    // 业务逻辑,先向服务器发起预支付请求,服务器返回支持订单信息。
    // ...

    // 先判断是否支持微信支付
    if ([self isSupportWechatPay]) {
        // 解析服务端返回的支付参数
        NSDictionary *payDictionary;
        // 使用 YYModel 将 JSON 数据转化为数据模型 HQLWechatPayRequestModel
        HQLWechatPayRequestModel *payRequestModel = [HQLWechatPayRequestModel modelWithJSON:payDictionary];
        // 向微信终端发起支付的消息结构体
        PayReq *request = [[PayReq alloc] init];
        request.partnerId = payRequestModel.partnerid;
        request.prepayId = payRequestModel.prepayid;
        request.package = payRequestModel.package;
        request.nonceStr = payRequestModel.noncestr;
        request.timeStamp = payRequestModel.timestamp;
        request.sign = payRequestModel.sign;
        // 发起微信支付
        [WXApi sendReq:request];
    }
}

@end

That’s all.

欢迎关注我的其它发布渠道