iOS 集成微信支付【转载】
目前项目里有微信支付的需求,调研过一段时间后,发现其实并没有想象中的那么困难。如果你只是想实现该功能,一个方法足以,但是若你想深入了解实现原理。就需要花费更多的功夫了。目前我只清楚微信支付需要做签名,一种是在后台签名,一种是自己在前端签名。其实这对前端来说代码量并没有多大的改变,最大的区别是在后台签名逻辑更容易理解,而在前端签名逻辑有些混乱。
小技巧:我在项目中集成类似的第三方功能时,如果需要对delegate进行操作,我会为这个功能,单独创建一个category类,这样避免项目出现多个第三方功能后,delegate里的代码十分混乱。
微信支付开发文档 http://mch.weixin.qq.com/wiki/doc/api/app.php?chapter=8_1
正文:
微信支付用到的文件
PS: 如果你在app内集成了微信分享功能,在分享的那个框架里,都能找到这些文件的,所以不需要在下载,直接用就行。
2.设置URL types
3、在Appdelegate中注册微信支付,我个人建议将注册后的内容输出一下,以便查看是否注册成功。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[WXApi registerApp:@"你的key值" withDescription:@"你的描述信息"];
BOOL isSuccess = [WXApi registerApp:@"你的key值" withDescription:@"你的描述信息"]; return YES;
}
4.微信回调
//处理微信通过URL启动App时传递的数据 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [WXApi handleOpenURL:url delegate:self];
} //微信回调
- (void)onResp:(BaseResp *)resp {
//errCode
switch (resp.errCode) {
case WXSuccess:
//成功回调
break;
default:
break;
}
}
5.调用微信支付(主要代码,后台签名)
PayReq* req = [[PayReq alloc] init]; req.partnerId = dict[@"entity"][@"partnerid"]; //商户号
req.prepayId = dict[@"entity"][@"prepayid"]; //预支付交易会话
req.nonceStr = dict[@"entity"][@"noncestr"]; //随机字符串 req.timeStamp = [dict[@"entity"][@"timestamp"] intValue]; //时间戳
req.package = dict[@"entity"][@"package"]; //扩展字段
req.sign = dict[@"entity"][@"sign"]; //签名 NSNumber *payOrder = dict[@"entity"][@"outTradeNo"]; SAVEUSERDEFAULT(payOrder, @"订单号"); //这一点坑比较大,在微信的官方文档里,有两种申请调用微信支付的方法sendReq和safeSendReq(安全方式),这两个方法不能确定什么时候哪个管用,我这里的解决办法就是这个不行换另一个。哈哈
[WXApi safeSendReq:req]; DLog(@"微信支付==%d",[WXApi sendReq:req]);
6.如果要在程序签名(这部分的有些难理解,我自己还没有理解透,有机会研究一下,在更新)
#import "payRequsestHandler.h"
#import "WXApi.h"
@interface ViewController () {
enum WXScene _scene;
NSString *Token;
long token_time;
}
@end
@implementation ViewController
- (instancetype)init
{
self = [super init];
if (self) {
_scene = WXSceneSession;
}
token_time = 0;
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
//向微信注册
//微信支付
UIButton *but2 = [[UIButton alloc]initWithFrame:CGRectMake(200, 100, 100, 40)];
[but2 setTitle:@"微信支付" forState:UIControlStateNormal];
but2.backgroundColor = [UIColor lightGrayColor];
[but2 addTarget:self action:@selector(wxpay) forControlEvents:UIControlEventTouchUpInside];
[but2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.view addSubview:but2];
}
//微信支付
- (void)wxpay
{
//商户号
NSString *PARTNER_ID = @"1900000109";
//商户密钥
NSString *PARTNER_KEY = @"8934e7d15453e97507ef794cf7b0519d";
//APPID
NSString *APPI_ID = @"wxd930ea5d5a258f4f";
//appsecret
NSString *APP_SECRET = @"db426a9829e4b49a0dcac7b4162da6b6";
//支付密钥
NSString *APP_KEY = @"L8LrMqqeGRxST5reouB0K66CaYAWpqhAVsq7ggKkxHCOastWksvuX1uvmvQclxaHoYd3ElNBrNO2DHnnzgfVG9Qs473M3DTOZug5er46FhuGofumV8H2FVR9qkjSlC5K";
//支付结果回调页面
NSString *NOTIFY_URL = @"http://localhost/pay/wx/notify_url.asp";
//订单标题
NSString *ORDER_NAME = @"Ios客户端签名支付 测试";
//订单金额,单位(分)
NSString *ORDER_PRICE = @"1";
//创建支付签名对象
payRequsestHandler *req = [payRequsestHandler alloc];
//初始化支付签名对象
[req init:APPI_ID app_secret:APP_SECRET partner_key:PARTNER_KEY app_key:APP_KEY];
//判断Token过期时间,10分钟内不重复获取,测试帐号多个使用,可能造成其他地方获取后不能用,需要即时获取
time_t now;
time(&now);
//if ( (now - token_time) > 0 )//非测试帐号调试请启用该条件判断
{
//获取Token
Token = [req GetToken];
//设置Token有效期为10分钟
token_time = now + 600;
//日志输出
NSLog(@"获取Token: %@\n",[req getDebugifo]);
}
if ( Token != nil){
//================================
//预付单参数订单设置
//================================
NSMutableDictionary *packageParams = [NSMutableDictionary dictionary];
[packageParams setObject: @"WX" forKey:@"bank_type"];
[packageParams setObject: ORDER_NAME forKey:@"body"];
[packageParams setObject: @"1" forKey:@"fee_type"];
[packageParams setObject: @"UTF-8" forKey:@"input_charset"];
[packageParams setObject: NOTIFY_URL forKey:@"notify_url"];
[packageParams setObject: [NSString stringWithFormat:@"%ld",time(0)] forKey:@"out_trade_no"];
[packageParams setObject: PARTNER_ID forKey:@"partner"];
[packageParams setObject: @"196.168.1.1" forKey:@"spbill_create_ip"];
[packageParams setObject: ORDER_PRICE forKey:@"total_fee"];
NSString *package, *time_stamp, *nonce_str, *traceid;
//获取package包
package = [req genPackage:packageParams];
//输出debug info
NSString *debug = [req getDebugifo];
NSLog(@"gen package: %@\n",package);
NSLog(@"生成package: %@\n",debug);
//设置支付参数
time_stamp = [NSString stringWithFormat:@"%ld", now];
nonce_str = [TenpayUtil md5:time_stamp];
traceid = @"mytestid_001";
NSMutableDictionary *prePayParams = [NSMutableDictionary dictionary];
[prePayParams setObject: APPI_ID forKey:@"appid"];
[prePayParams setObject: APP_KEY forKey:@"appkey"];
[prePayParams setObject: nonce_str forKey:@"noncestr"];
[prePayParams setObject: package forKey:@"package"];
[prePayParams setObject: time_stamp forKey:@"timestamp"];
[prePayParams setObject: traceid forKey:@"traceid"];
//生成支付签名
NSString *sign;
sign = [req createSHA1Sign:prePayParams];
//增加非参与签名的额外参数
[prePayParams setObject: @"sha1" forKey:@"sign_method"];
[prePayParams setObject: sign forKey:@"app_signature"];
//获取prepayId
NSString *prePayid;
prePayid = [req sendPrepay:prePayParams];
//输出debug info
debug = [req getDebugifo];
NSLog(@"提交预付单: %@\n",debug);
if ( prePayid != nil) {
//重新按提交格式组包,微信客户端5.0.3以前版本只支持package=Sign=***格式,须考虑升级后支持携带package具体参数的情况
//package = [NSString stringWithFormat:@"Sign=%@",package];
package = @"Sign=WXPay";
//签名参数列表
NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
[signParams setObject: APPI_ID forKey:@"appid"];
[signParams setObject: APP_KEY forKey:@"appkey"];
[signParams setObject: nonce_str forKey:@"noncestr"];
[signParams setObject: package forKey:@"package"];
[signParams setObject: PARTNER_ID forKey:@"partnerid"];
[signParams setObject: time_stamp forKey:@"timestamp"];
[signParams setObject: prePayid forKey:@"prepayid"];
//生成签名
sign = [req createSHA1Sign:signParams];
//输出debug info
debug = [req getDebugifo];
NSLog(@"调起支付签名: %@\n",debug);
//调起微信支付
PayReq* req = [[PayReq alloc] init];
req.openID = APPI_ID;
req.partnerId = PARTNER_ID;
req.prepayId = prePayid;
req.nonceStr = nonce_str;
req.timeStamp = now;
req.package = package;
req.sign = sign;
[WXApi safeSendReq:req];
}else{
/*long errcode = [req getLasterrCode];
if ( errcode == 40001 )
{//Token实效,重新获取
Token = [req GetToken];
token_time = now + 600;
NSLog(@"获取Token: %@\n",[req getDebugifo]);
};*/
NSLog(@"获取prepayid失败\n");
[self alert:@"提示信息" msg:debug];
}
}else{
NSLog(@"获取Token失败\n");
[self alert:@"提示信息" msg:@"获取Token失败"];
}
}
//客户端提示信息
- (void)alert:(NSString *)title msg:(NSString *)msg
{
UIAlertView *alter = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alter show];
}
//- (void)onReq:(BaseReq *)req {
// NSLog(@"qwe123");
//}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end

iOS 集成微信支付【转载】的更多相关文章
- iOS集成微信支付
微信支付的开发 前言:之前听说过微信支付有很多坑,其实没有想象的那么坑,整体感觉很容易上手,按照它的流程来不会有错!PS:官方的流程看的TMD烦,好啦,废话有点多,进入开发.(ps:每个微信的版本一直 ...
- iOS集成微信支付各种坑收录
统一下单的参数要拼接成XML格式,使用AFN请求时要对参数转义,直接传入字典给AFN无法识别(这个接口微信demo中并没有提供示例) AFHTTPRequestOperationManager *ma ...
- 手把手教你springboot集成微信支付
20220727 最近要做一个微信小程序,需要微信支付,所以研究了下怎么在 java 上集成微信支付功能,特此记录下. 本文完整代码:点击跳转 准备工作 小程序开通微信支付 首先需要在微信支付的官网点 ...
- iOS开发集成微信支付
首先需要理清楚流程: 1.用户使用APP客户端,选择商品下单. 2.商户客户端(就是你做的APP)将用户的商品数据传给商户服务器,请求生成支付订单. 3.商户后台调用统一下单API向微信的服务器发送请 ...
- iOS之微信支付
前言:下面介绍微信支付的开发流程的细节,图文并茂,你可以按照我的随笔流程过一遍代码.包你也学会了微信支付.而且支付也是面试常问的内容. 正文: 1.首先在开始使用微信支付之前,有一些东西是开发者必须要 ...
- iOS - WXPay 微信支付
1.微信支付申请 微信支付官方集成指引 微信支付官方集成指导视频 微信 APP 支付开发者文档 微信公众平台 微信开放平台 微信商户平台 1.1 微信 APP 支付申请步骤 APP 支付:APP 支付 ...
- IOS开发--微信支付
前言:下面介绍微信支付的开发流程的细节,图文并茂,你可以按照我的随笔流程过一遍代码.包你也学会了微信支付.而且支付也是面试常问的内容. 正文: 1.首先在开始使用微信支付之前,有一些东西是开发者必须要 ...
- 关于IOS调用微信支付jsapi不起作用的解决方法
微信支付时,安卓机调用 jsapi可以支付,IOS就不行,点击立即支付,直接返回原立即支付页面,跟刷新页面差不多,解决方案很简单:两句话而已. 不得不说,微信支付坑太多了,我擦..... <sc ...
- ***CodeIgniter集成微信支付(转)
微信支付Native扫码支付模式二之CodeIgniter集成篇 http://www.cnblogs.com/24la/p/wxpay-native-qrcode-codeigniter.html ...
随机推荐
- [SHOI2014]信号增幅仪
题目大意: 平面直角坐标系中散落着n个点,一个椭圆的长半轴在对于x轴逆时针旋转α度的角度上,且长半轴是短半轴的k倍. 问短半轴至少要多长才能覆盖所有的点? 思路: 首先把坐标顺时针旋转α度,然后把所有 ...
- [美团 CodeM 初赛 Round A]最长树链
题目大意: 给你一棵带点权的树,找出一个最长的树链满足链上点权的最大公因数不为1. 思路: 暴力DP. 对于每个点,记录一下以这个点为一个端点的所有链的最大公因数及长度. 然后暴力转移一下,时间复杂度 ...
- BUG The user specified as a definer ('root'@'%') does not exist' in
BUG描述:通过点击实现页面无刷新提交数据. 链接服务器数据库时-提交成功 当把数据库下载到本地后链接,提交失败 查看日志显示:The user specified as a definer ('ro ...
- opencv在vc2010 express下环境搭建方法笔记+空白通用工程(已编译测试通过)(提供下载)
opencv在VC2010 express版本下的环境搭建可以参见下面的wiki,这里面讲的非常清楚. http://wiki.opencv.org.cn/index.php/VC_2010_Expr ...
- 现在就可以使用的5个 ES6 特性
小编推荐:掘金是一个高质量的技术社区,从 ECMAScript 6 到 Vue.js,性能优化到开源类库,让你不错过前端开发的每一个技术干货.各大应用市场搜索「掘金」即可下载APP,技术干货尽在掌握. ...
- vim 代码注释插件
参考: 1.http://www.vim.org/scripts/script.php?script_id=1218 2.http://www.dutor.net/index.php/2010/05/ ...
- 转载:win10 下安装Oracle 11g(问题:环境不满足最低要求)
安装oracle11g时遇到INS-13001环境不满足最低要求 在以管理员身份运行setup.exe之后,出现了:[INS-13001]环境不满足最低要求,通过网上搜索之后找到了解决途径 首先,打开 ...
- Apache -Common-lang包使用
原文:http://weigang-gao.iteye.com/blog/2188739 ArrayUtils – 用于对数组的操作,如添加.查找.删除.子数组.倒序.元素类型转换等: BitFiel ...
- iOS:Masonry练习详解
Masonry练习详解 添加约束的方式: 1.通过使用NSLayoutConstraints添加约束到约束数组中,之前必须设置translatesAutoresizingMaskIntoConst ...
- pip install py-stringsimjoin error: INCLUDE environment variable is empty
在用pip install py-stringsimjoin的时候报错error: INCLUDE environment variable is empty,后来在网上搜索下了说是需要下载安装VCF ...