iOS - WXPay 微信支付
1、微信支付申请
1.1 微信 APP 支付申请步骤
- APP 支付:APP 支付又称移动端支付,是商户通过在移动端应用 APP 中集成开放 SDK 调起微信支付模块完成支付的模式。
1.1.1 第 1 阶段
1、注册微信开放平台帐号,注册成为微信开放平台开发者。
2、认证开发者资质,开发者资质认证通过后才可申请微信支付,申请审核服务费:300 元/次(年)。
3、创建 APP 并提交审核,提交你的 APP 基本信息,通过开放平台应用审核,以获得 AppID。
微信认证审核时间在 7 个工作日左右。
1.1.2 第 2 阶段
1、提交资料申请微信支付,申请成功后可以在 APP 中调用微信支付来付款。
商户在微信公众平台(申请扫码支付、公众号支付)或开放平台(申请APP支付)按照相应提示,申请相应微信支付模式。微信支付工作人员审核资料无误后开通相应的微信支付权限。微信支付申请审核通过后,商户在申请资料填写的邮箱中收取到由微信支付小助手发送的邮件,此邮件包含开发时需要使用的支付账户信息。
邮件中的账户参数与接口API参数对应关系:
约 1~5 个工作日。
1.1.3 第 3 阶段
2、启动设计和开发,支付接口已可以在开发环境下调用调试。
成功接入微信支付。
1.2 微信 APP 支付相关说明
1.2.1 支付账户
商户在微信公众平台(申请扫码支付、公众号支付)或开放平台(申请APP支付)按照相应提示,申请相应微信支付模式。微信支付工作人员审核资料无误后开通相应的微信支付权限。微信支付申请审核通过后,商户在申请资料填写的邮箱中收取到由微信支付小助手发送的邮件,此邮件包含开发时需要使用的支付账户信息。
账户参数说明:
1.2.2 协议规则
商户接入微信支付,调用API必须遵循以下规则:
1.2.3 参数规定
参数规定:
1.2.4 安全规范
-
- 签名算法
- 生成随机数算法
- 商户证书
- 商户回调API安全
1.2.5 业务流程
以下是交互时序图,统一下单API、支付结果通知API和查询订单API等都涉及签名过程,调用都必须在商户服务器端完成。
商户系统和微信支付系统主要交互说明:
- 步骤1:用户在商户 APP 中选择商品,提交订单,选择微信支付。
- 步骤2:商户后台收到用户支付单,调用微信支付统一下单接口。参见【统一下单 API】。
- 步骤3:统一下单接口返回正常的 prepay_id,再按签名规范重新生成签名后,将数据传输给 APP。参与签名的字段名为 appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package 的值格式为 Sign=WXPay。
- 步骤4:商户 APP 调起微信支付。api 参见本章节【app 端开发步骤说明】
- 步骤5:商户后台接收支付通知。api 参见【支付结果通知 API】
- 步骤6:商户后台查询支付结果。,api 参见【查询订单API】
1.2.6 API 列表
1.2.7 验收流程
2、微信 APP 支付开发
说明:
商户服务端:
- 负责生成订单及签名,及接受支付异步通知。
APP 客户端:
- 负责使用服务端传来的订单信息调用微信支付接口,及根据 SDK 同步返回的支付结果展示结果页。
服务端接入:
- API 密钥必须放在商户服务端,签名过程必须放在商户服务端。
2.1 微信 APP 支付集成设置
1、下载 iOS 端开发工具包 WeChatSDK,并添加到创建的工程中。WeChatSDK 中有 5 个文件,分别为:
libWeChatSDK.a // 静态库文件
WechatAuthSDK.h // 微信登陆等接口
WXApi.h // 所有 Api 接口
WXApiObject.h // Api 对象,包含所有接口和对象数据定义
README.txt // 所有版本的使用说明
2、iOS 9 + 系统策略更新,限制了 http 协议的访问,此外应用需要在 “Info.plist” 中将要使用的 URL Schemes 列为白名单,才可正常检查其他应用是否安装。
受此影响,当你的应用在 iOS 9 + 中需要使用微信 SDK 的相关能力(分享、收藏、支付、登录等)时,需要在 “Info.plist” 里增加如下代码:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>weixin</string>
</array>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
商户在微信开放平台申请开发 APP 应用后,微信开放平台会生成 APP 的唯一标识 APPID。在 Xcode 中打开项目,设置项目属性中的 URL Schemes 为您的 APPID。在 项目设置 => TARGETS => Info => URL Types 中点击加号按钮添加。
3、添加 SDK 的依赖库和框架。在 项目设置 => TARGETS => Build Phases => Link Binary With Libraries 中依次添加 README.txt 说明文档中提及的以下库或框架:
SystemConfiguration.framework
CoreTelephony.framework
Security.framework
CFNetwork.framework libz.dylib
libsqlite3.0.dylib
libWeChatSDK.a // 导入 SDK 时已自动添加
- 另外还需要添加官方没有提到的下列依赖库:
libc++.tbd
4、如果接入微信的 sdk,在 delegate 里加入这句注册代码 WXApi registerApp: 运行后程序就崩溃,原因是库里用了某个类的扩展,编译时这些扩展没有编译,所以崩溃的。只需要在 项目设置 => TARGETS => Build Settings => Linking => Other Linker Flags 中添加上 -ObjC 即可,注意 O 和 C 都为大写。
2.2 微信 APP 支付集成
详细代码见 GitHub
Objective-C
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 向微信终端程序注册第三方应用 APPID: wxb4ba3c02aa476ea1
[WXApi registerApp:@"wxb4ba3c02aa476ea1" withDescription:@"QWeChatPayDemo 1.0"]; return YES;
} // 微信支付回调,当用户通过其他应用启动本应用时,会回调这个方法 // NS_DEPRECATED_IOS(2_0, 9_0)
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [WXApi handleOpenURL:url delegate:self];
} // NS_DEPRECATED_IOS(2_0, 9_0)
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [WXApi handleOpenURL:url delegate:self];
} // NS_AVAILABLE_IOS(9_0) 9.0 以后使用新 API 接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options {
return [WXApi handleOpenURL:url delegate:self];
} - (void)onResp:(BaseResp *)resp { if([resp isKindOfClass:[PayResp class]]){ // 支付返回结果,实际支付结果需要去微信服务器端查询
NSString *strMsg; switch (resp.errCode) { case WXSuccess:
strMsg = @"支付成功!";
NSLog(@"支付成功:retcode = %d", resp.errCode);
break; default:
strMsg = [NSString stringWithFormat:@"支付失败!retcode = %d, retstr = %@", resp.errCode, resp.errStr];
NSLog(@"支付失败:retcode = %d, retstr = %@", resp.errCode, resp.errStr);
break;
} // 显示提示信息
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"支付结果"
message:strMsg
preferredStyle:UIAlertControllerStyleAlert]; [self.window.rootViewController presentViewController:alert
animated:YES
completion:^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[alert dismissViewControllerAnimated:YES completion:nil];
});
}];
}
}
ViewController.m
// 判断是否安装了微信
if (![WXApi isWXAppInstalled]) {
NSLog(@"没有安装微信");
return;
} // 判断是否支持微信支付
if (![WXApi isWXAppSupportApi]) {
NSLog(@"不支持微信支付");
return;
} NSMutableDictionary *params = [NSMutableDictionary dictionary]; // 在此设置商户服务端需要的参数
params[WXTOTALFEE] = @"1";
params[WXEQUIPMENTIP] = [self fetchIPAddress]; // 向商户微信支付服务器端请求微信预支付信息
AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager]; [sessionManager POST:QCUrlUserWeChatPay
parameters:params
progress:nil
success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { // 解析商户微信支付服务器端返回的数据,获得预支付信息和签名等 NSLog(@"responseObject = %@",responseObject); if (responseObject != nil) { // 发起微信支付
PayReq *request = [[PayReq alloc] init]; // 设置参数
request.openID = [responseObject objectForKey:WXAPPID];
request.partnerId = [responseObject objectForKey:WXMCHID];
request.prepayId= [responseObject objectForKey:WXPREPAYID];
request.nonceStr= [responseObject objectForKey:WXNONCESTR];
request.timeStamp= [[responseObject objectForKey:@"timestamp"] intValue];
request.package = @"Sign=WXPay";
request.sign = [responseObject objectForKey:@"sign"]; NSLog(@"%@--%@--%@--%@--%@--%d--%@",request.openID,request.partnerId,request.prepayId,
request.package,request.nonceStr,request.timeStamp,request.sign); // 调用微信发起支付
[WXApi sendReq:request];
} } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"向商户微信支付服务器端请求预支付信息失败:%@", error.localizedDescription);
}];
iOS - WXPay 微信支付的更多相关文章
- iOS之微信支付
前言:下面介绍微信支付的开发流程的细节,图文并茂,你可以按照我的随笔流程过一遍代码.包你也学会了微信支付.而且支付也是面试常问的内容. 正文: 1.首先在开始使用微信支付之前,有一些东西是开发者必须要 ...
- IOS开发--微信支付
前言:下面介绍微信支付的开发流程的细节,图文并茂,你可以按照我的随笔流程过一遍代码.包你也学会了微信支付.而且支付也是面试常问的内容. 正文: 1.首先在开始使用微信支付之前,有一些东西是开发者必须要 ...
- iOS开发微信支付
现在基本所有的App都会接入支付宝支付以及微信支付,也有很多第三方提供给你 SDK帮你接入,但是这种涉及到支付的东西还是自己服务器搞来的好一些,其实搞懂了 逻辑非常的简单,下面直接给大家说说下基本流程 ...
- iOS 集成微信支付【转载】
目前项目里有微信支付的需求,调研过一段时间后,发现其实并没有想象中的那么困难.如果你只是想实现该功能,一个方法足以,但是若你想深入了解实现原理.就需要花费更多的功夫了.目前我只清楚微信支付需要做签名, ...
- 关于IOS调用微信支付jsapi不起作用的解决方法
微信支付时,安卓机调用 jsapi可以支付,IOS就不行,点击立即支付,直接返回原立即支付页面,跟刷新页面差不多,解决方案很简单:两句话而已. 不得不说,微信支付坑太多了,我擦..... <sc ...
- iOS: 实现微信支付
一.介绍: 现在的消费越来越方便,直接带个手机用各种三方的支付平台进行支付就行,例如微信.支付宝.现在正好我所做的项目中用到了微信支付,今天就来整理一下. 二.准备: 1.去微信官方开发者平台注册开发 ...
- iOS集成微信支付
微信支付的开发 前言:之前听说过微信支付有很多坑,其实没有想象的那么坑,整体感觉很容易上手,按照它的流程来不会有错!PS:官方的流程看的TMD烦,好啦,废话有点多,进入开发.(ps:每个微信的版本一直 ...
- iOS开发微信支付的介绍与实现
1.前期准备 1) 到微信开放平台注册账号 需要登录邮箱验证 填写您的商户信息 2) 进入管理中心 --- 移动应用 --- 创建移动应用 --- 根据页面完善应用资料 3) 审核过后,通过应用详情页 ...
- iOS集成微信支付各种坑收录
统一下单的参数要拼接成XML格式,使用AFN请求时要对参数转义,直接传入字典给AFN无法识别(这个接口微信demo中并没有提供示例) AFHTTPRequestOperationManager *ma ...
随机推荐
- android自定义拍照
调用系统相机,然后在自己的surfaceview上预览,拍照,不废话,直接上源码 package com.example.customecamera; import java.io.File; imp ...
- j2ee部分
j2ee部分 1.BS与CS的联系与区别. C/S是Client/Server的缩写.服务器通常采用高性能的PC.工作站或小型机,并采用大型数据库系统,如Oracle.Sybase.InFORMix或 ...
- 为什么要配置sdk-tools/platform-toools?
为了方便使用Android SDK包含的开发工具,我们在系统环境变量中的Path设置Android SDK的安装目录下的tools目录. Android SDK中: platform-tools里有a ...
- paper 128:奇异值分解(SVD) --- 线性变换几何意义[转]
PS:一直以来对SVD分解似懂非懂,此文为译文,原文以细致的分析+大量的可视化图形演示了SVD的几何意义.能在有限的篇幅把这个问题讲解的如此清晰,实属不易.原文举了一个简单的图像处理问题,简单形象,真 ...
- Python __builtins__模块拾穗
1.isinstance函数:除了以一个类型作为参数,还可以以一个类型元组作为参数. isinstance(obj,basestring)===isinstance(obj,(str,unicode) ...
- 《zw版·Halcon-delphi系列原创教程》 Halcon分类函数016,xld,xld轮廓
<zw版·Halcon-delphi系列原创教程> Halcon分类函数016,xld,xld轮廓 为方便阅读,在不影响说明的前提下,笔者对函数进行了简化: :: 用符号“**”,替换:“ ...
- jquery.serialize
jQuery - serialize() 方法 serialize() 方法通过序列化表单值,创建 URL 编码文本字符串. serialize()函数用于序列化一组表单元素,将表单内容编码为用于提交 ...
- mysql count(*)和count(列)速率
count(*)通常是对主键进行索引扫描,count(列)不一定 count(*)是统计表中所有符合的记录总数,count(列)是计算表中所有符合的列的记录数 count的时候,如果没有where限制 ...
- SQL 还原数据库
1. 查看 SQL Server 2000 中 Northwind 数据库文件的逻辑文件名(logical file name)和物理文件路径(operation system file name): ...
- Android 6.0 权限请求
在申请权限之前一定要在清单配置文件中添加该权限private static final int MY_PERMISSIONS_REQUEST_RECORD_AUDIO = 1; //随便定义 publ ...